symmetric-encryption 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/symmetric_encryption/reader.rb +71 -35
- data/lib/symmetric_encryption/symmetric_encryption.rb +3 -3
- data/lib/symmetric_encryption/version.rb +1 -1
- data/lib/symmetric_encryption/writer.rb +43 -26
- data/nbproject/private/private.xml +2 -2
- data/test/reader_test.rb +34 -4
- data/test/writer_test.rb +4 -0
- metadata +4 -8
- data/symmetric-encryption-0.2.0.gem +0 -0
- data/symmetric-encryption-0.4.0.gem +0 -0
- data/symmetric-encryption-0.5.0.gem +0 -0
- data/symmetric-encryption-0.5.1.gem +0 -0
@@ -4,34 +4,6 @@ module SymmetricEncryption
|
|
4
4
|
# Features:
|
5
5
|
# * Decryption on the fly whilst reading files
|
6
6
|
# * Large file support by only buffering small amounts of data in memory
|
7
|
-
#
|
8
|
-
# # Example: Read and decrypt a line at a time from a file
|
9
|
-
# SymmetricEncryption::Reader.open('test_file') do |file|
|
10
|
-
# file.each_line {|line| p line }
|
11
|
-
# end
|
12
|
-
#
|
13
|
-
# # Example: Read and decrypt entire file in memory
|
14
|
-
# # Not recommended for large files
|
15
|
-
# SymmetricEncryption::Reader.open('test_file') {|f| f.read }
|
16
|
-
#
|
17
|
-
# # Example: Reading a limited number of bytes at a time from the file
|
18
|
-
# SymmetricEncryption::Reader.open('test_file') do |file|
|
19
|
-
# file.read(1)
|
20
|
-
# file.read(5)
|
21
|
-
# file.read
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# # Example: Read and decrypt 5 bytes at a time until the end of file is reached
|
25
|
-
# SymmetricEncryption::Reader.open('test_file') do |file|
|
26
|
-
# while !file.eof? do
|
27
|
-
# file.read(5)
|
28
|
-
# end
|
29
|
-
# end
|
30
|
-
#
|
31
|
-
# # Example: Read, Unencrypt and decompress data in a file
|
32
|
-
# SymmetricEncryption::Reader.open('encrypted_compressed.zip', :compress => true) do |file|
|
33
|
-
# file.each_line {|line| p line }
|
34
|
-
# end
|
35
7
|
class Reader
|
36
8
|
# Open a file for reading, or use the supplied IO Stream
|
37
9
|
#
|
@@ -62,6 +34,45 @@ module SymmetricEncryption
|
|
62
34
|
# Default: 4096
|
63
35
|
#
|
64
36
|
# Note: Decryption occurs before decompression
|
37
|
+
#
|
38
|
+
# # Example: Read and decrypt a line at a time from a file
|
39
|
+
# SymmetricEncryption::Reader.open('test_file') do |file|
|
40
|
+
# file.each_line {|line| p line }
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# # Example: Read and decrypt entire file in memory
|
44
|
+
# # Not recommended for large files
|
45
|
+
# SymmetricEncryption::Reader.open('test_file') {|f| f.read }
|
46
|
+
#
|
47
|
+
# # Example: Reading a limited number of bytes at a time from the file
|
48
|
+
# SymmetricEncryption::Reader.open('test_file') do |file|
|
49
|
+
# file.read(1)
|
50
|
+
# file.read(5)
|
51
|
+
# file.read
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# # Example: Read and decrypt 5 bytes at a time until the end of file is reached
|
55
|
+
# SymmetricEncryption::Reader.open('test_file') do |file|
|
56
|
+
# while !file.eof? do
|
57
|
+
# file.read(5)
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# # Example: Read, Unencrypt and decompress data in a file
|
62
|
+
# SymmetricEncryption::Reader.open('encrypted_compressed.zip', :compress => true) do |file|
|
63
|
+
# file.each_line {|line| p line }
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# # Example: Reading from a CSV file
|
67
|
+
#
|
68
|
+
# require 'fastercsv'
|
69
|
+
# begin
|
70
|
+
# # Must supply :row_sep for FasterCSV otherwise it will attempt to rewind the file etc.
|
71
|
+
# csv = FasterCSV.new(SymmetricEncryption::Reader.open('csv_encrypted'), :row_sep => "\n")
|
72
|
+
# csv.each {|row| p row}
|
73
|
+
# ensure
|
74
|
+
# csv.close if csv
|
75
|
+
# end
|
65
76
|
def self.open(filename_or_stream, options={}, &block)
|
66
77
|
raise "options must be a hash" unless options.respond_to?(:each_pair)
|
67
78
|
mode = options.fetch(:mode, 'r')
|
@@ -71,9 +82,9 @@ module SymmetricEncryption
|
|
71
82
|
begin
|
72
83
|
file = self.new(ios, options)
|
73
84
|
file = Zlib::GzipReader.new(file) if file.compressed? || compress
|
74
|
-
block.call(file)
|
85
|
+
block ? block.call(file) : file
|
75
86
|
ensure
|
76
|
-
file.close if file
|
87
|
+
file.close if block && file
|
77
88
|
end
|
78
89
|
end
|
79
90
|
|
@@ -89,8 +100,8 @@ module SymmetricEncryption
|
|
89
100
|
if buf.start_with?(SymmetricEncryption::MAGIC_HEADER)
|
90
101
|
# Header includes magic header and version byte
|
91
102
|
# Remove header and extract flags
|
92
|
-
header, flags = buf.slice!(0..MAGIC_HEADER_SIZE).unpack(MAGIC_HEADER_UNPACK)
|
93
|
-
@compressed = flags & 0b1000_0000_0000_0000
|
103
|
+
header, flags = buf.slice!(0..MAGIC_HEADER_SIZE+1).unpack(MAGIC_HEADER_UNPACK)
|
104
|
+
@compressed = (flags & 0b1000_0000_0000_0000) != 0
|
94
105
|
@version = @compressed ? flags - 0b1000_0000_0000_0000 : flags
|
95
106
|
else
|
96
107
|
@version = options[:version]
|
@@ -179,15 +190,27 @@ module SymmetricEncryption
|
|
179
190
|
end
|
180
191
|
|
181
192
|
# Reads a single decrypted line from the file up to and including the optional sep_string.
|
182
|
-
#
|
193
|
+
# Raises EOFError on eof
|
183
194
|
# The stream must be opened for reading or an IOError will be raised.
|
184
195
|
def readline(sep_string = "\n")
|
196
|
+
gets(sep_string) || raise(EOFError.new("End of file reached when trying to read a line"))
|
197
|
+
end
|
198
|
+
|
199
|
+
# Reads a single decrypted line from the file up to and including the optional sep_string.
|
200
|
+
# A sep_string of nil reads the entire contents of the file
|
201
|
+
# Returns nil on eof
|
202
|
+
# The stream must be opened for reading or an IOError will be raised.
|
203
|
+
def gets(sep_string)
|
204
|
+
return read if sep_string.nil?
|
205
|
+
|
185
206
|
# Read more data until we get the sep_string
|
186
207
|
while (index = @read_buffer.index(sep_string)).nil? && !@ios.eof?
|
187
208
|
read_block
|
188
209
|
end
|
189
210
|
index ||= -1
|
190
|
-
@read_buffer.slice!(0..index)
|
211
|
+
data = @read_buffer.slice!(0..index)
|
212
|
+
return nil if data.length == 0 && eof?
|
213
|
+
data
|
191
214
|
end
|
192
215
|
|
193
216
|
# ios.each(sep_string="\n") {|line| block } => ios
|
@@ -196,7 +219,7 @@ module SymmetricEncryption
|
|
196
219
|
# ios must be opened for reading or an IOError will be raised.
|
197
220
|
def each_line(sep_string = "\n")
|
198
221
|
while !eof?
|
199
|
-
yield
|
222
|
+
yield gets(sep_string)
|
200
223
|
end
|
201
224
|
self
|
202
225
|
end
|
@@ -208,6 +231,19 @@ module SymmetricEncryption
|
|
208
231
|
(@read_buffer.size == 0) && @ios.eof?
|
209
232
|
end
|
210
233
|
|
234
|
+
# Return the approximate offset in bytes of the current input stream
|
235
|
+
# Since the encrypted data size does not match the unencrypted size
|
236
|
+
# this value cannot be guaranteed. Especially if compression is turned on
|
237
|
+
def pos
|
238
|
+
@ios.pos - @read_buffer.size
|
239
|
+
end
|
240
|
+
|
241
|
+
# Rewind back to the beginning of the file
|
242
|
+
def rewind
|
243
|
+
@read_buffer = ''
|
244
|
+
@ios.rewind
|
245
|
+
end
|
246
|
+
|
211
247
|
private
|
212
248
|
|
213
249
|
# Read a block of data and append the decrypted data in the read buffer
|
@@ -21,8 +21,8 @@ module SymmetricEncryption
|
|
21
21
|
# Returns the Primary Symmetric Cipher being used
|
22
22
|
# If a version is supplied, then the cipher matching that version will be
|
23
23
|
# returned or nil if no match was found
|
24
|
-
def self.cipher(version =
|
25
|
-
return @@cipher if version.nil? || (@@cipher.version == version)
|
24
|
+
def self.cipher(version = 0)
|
25
|
+
return @@cipher if version.nil? || (version == 0) || (@@cipher.version == version)
|
26
26
|
secondary_ciphers.find {|c| c.version == version}
|
27
27
|
end
|
28
28
|
|
@@ -190,7 +190,7 @@ module SymmetricEncryption
|
|
190
190
|
unless defined? MAGIC_HEADER
|
191
191
|
MAGIC_HEADER = '@EnC'
|
192
192
|
MAGIC_HEADER_SIZE = MAGIC_HEADER.size
|
193
|
-
MAGIC_HEADER_UNPACK = "
|
193
|
+
MAGIC_HEADER_UNPACK = "a#{MAGIC_HEADER_SIZE}v"
|
194
194
|
end
|
195
195
|
|
196
196
|
protected
|
@@ -1,29 +1,13 @@
|
|
1
1
|
module SymmetricEncryption
|
2
|
+
# Write to encrypted files and other IO streams
|
3
|
+
#
|
4
|
+
# Features:
|
5
|
+
# * Encryption on the fly whilst writing files.
|
6
|
+
# * Large file support by only buffering small amounts of data in memory
|
7
|
+
# * Underlying buffering to ensure that encrypted data fits
|
8
|
+
# into the Symmetric Encryption Cipher block size
|
9
|
+
# Only the last block in the file will be padded if it is less than the block size
|
2
10
|
class Writer
|
3
|
-
# Write to encrypted files and other IO streams
|
4
|
-
#
|
5
|
-
# Features:
|
6
|
-
# * Encryption on the fly whilst writing files.
|
7
|
-
# * Large file support by only buffering small amounts of data in memory
|
8
|
-
# * Underlying buffering to ensure that encrypted data fits
|
9
|
-
# into the Symmetric Encryption Cipher block size
|
10
|
-
# Only the last block in the file will be padded if it is less than the block size
|
11
|
-
#
|
12
|
-
# # Example: Encrypt and write data to a file
|
13
|
-
# SymmetricEncryption::Writer.open('test_file') do |file|
|
14
|
-
# file.write "Hello World\n"
|
15
|
-
# file.write "Keep this secret"
|
16
|
-
# end
|
17
|
-
#
|
18
|
-
# # Example: Compress, Encrypt and write data to a file
|
19
|
-
# SymmetricEncryption::Writer.open('encrypted_compressed.zip', :compress => true) do |file|
|
20
|
-
# file.write "Hello World\n"
|
21
|
-
# file.write "Compress this\n"
|
22
|
-
# file.write "Keep this safe and secure\n"
|
23
|
-
# end
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
11
|
# Open a file for writing, or use the supplied IO Stream
|
28
12
|
#
|
29
13
|
# Parameters:
|
@@ -57,6 +41,29 @@ module SymmetricEncryption
|
|
57
41
|
#
|
58
42
|
# Note: Compression occurs before encryption
|
59
43
|
#
|
44
|
+
#
|
45
|
+
# # Example: Encrypt and write data to a file
|
46
|
+
# SymmetricEncryption::Writer.open('test_file') do |file|
|
47
|
+
# file.write "Hello World\n"
|
48
|
+
# file.write "Keep this secret"
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# # Example: Compress, Encrypt and write data to a file
|
52
|
+
# SymmetricEncryption::Writer.open('encrypted_compressed.zip', :compress => true) do |file|
|
53
|
+
# file.write "Hello World\n"
|
54
|
+
# file.write "Compress this\n"
|
55
|
+
# file.write "Keep this safe and secure\n"
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# # Example: Writing to a CSV file
|
59
|
+
# require 'fastercsv'
|
60
|
+
# begin
|
61
|
+
# # Must supply :row_sep for FasterCSV otherwise it will attempt to read from and then rewind the file
|
62
|
+
# csv = FasterCSV.new(SymmetricEncryption::Writer.open('csv_encrypted'), :row_sep => "\n")
|
63
|
+
# csv << [1,2,3,4,5]
|
64
|
+
# ensure
|
65
|
+
# csv.close if csv
|
66
|
+
# end
|
60
67
|
def self.open(filename_or_stream, options={}, &block)
|
61
68
|
raise "options must be a hash" unless options.respond_to?(:each_pair)
|
62
69
|
mode = options.fetch(:mode, 'w')
|
@@ -66,9 +73,9 @@ module SymmetricEncryption
|
|
66
73
|
begin
|
67
74
|
file = self.new(ios, options)
|
68
75
|
file = Zlib::GzipWriter.new(file) if compress
|
69
|
-
block.call(file)
|
76
|
+
block ? block.call(file) : file
|
70
77
|
ensure
|
71
|
-
file.close if file
|
78
|
+
file.close if block && file
|
72
79
|
end
|
73
80
|
end
|
74
81
|
|
@@ -114,6 +121,16 @@ module SymmetricEncryption
|
|
114
121
|
data.length
|
115
122
|
end
|
116
123
|
|
124
|
+
# Write to the IO Stream as encrypted data
|
125
|
+
# Returns self
|
126
|
+
#
|
127
|
+
# Example:
|
128
|
+
# file << "Hello.\n" << "This is Jack"
|
129
|
+
def <<(data)
|
130
|
+
write(data)
|
131
|
+
self
|
132
|
+
end
|
133
|
+
|
117
134
|
private
|
118
135
|
|
119
136
|
# Write the Encryption header if this is the first write
|
@@ -6,11 +6,11 @@
|
|
6
6
|
<line>62</line>
|
7
7
|
</file>
|
8
8
|
<file>
|
9
|
-
<url>lib/symmetric_encryption/
|
9
|
+
<url>lib/symmetric_encryption/symmetric_encryption.rb</url>
|
10
10
|
<line>60</line>
|
11
11
|
</file>
|
12
12
|
<file>
|
13
|
-
<url>lib/symmetric_encryption/
|
13
|
+
<url>lib/symmetric_encryption/encryption.rb</url>
|
14
14
|
<line>60</line>
|
15
15
|
</file>
|
16
16
|
</editor-bookmarks>
|
data/test/reader_test.rb
CHANGED
@@ -22,7 +22,6 @@ class ReaderTest < Test::Unit::TestCase
|
|
22
22
|
@data_str = @data.inject('') {|sum,str| sum << str}
|
23
23
|
@data_len = @data_str.length
|
24
24
|
@data_encrypted = SymmetricEncryption.cipher.encrypt(@data_str)
|
25
|
-
@filename = '._test'
|
26
25
|
end
|
27
26
|
|
28
27
|
should "decrypt from string stream as a single read" do
|
@@ -68,9 +67,40 @@ class ReaderTest < Test::Unit::TestCase
|
|
68
67
|
end
|
69
68
|
end
|
70
69
|
|
71
|
-
|
70
|
+
context "reading from file" do
|
71
|
+
# With and without header
|
72
|
+
[false, true].each do |header|
|
73
|
+
context "with#{'out' unless header} header" do
|
74
|
+
setup do
|
75
|
+
@filename = '._test'
|
76
|
+
@options = { :header => header }
|
77
|
+
# Create encrypted file
|
78
|
+
SymmetricEncryption::Writer.open(@filename, @options) do |file|
|
79
|
+
@data.inject(0) {|sum,str| sum + file.write(str)}
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
teardown do
|
84
|
+
File.delete(@filename) if File.exist?(@filename)
|
85
|
+
end
|
86
|
+
|
87
|
+
should "decrypt from file in a single read" do
|
88
|
+
decrypted = SymmetricEncryption::Reader.open(@filename) {|file| file.read}
|
89
|
+
assert_equal @data_str, decrypted
|
90
|
+
end
|
91
|
+
|
92
|
+
should "decrypt from file a line at a time" do
|
93
|
+
decrypted = SymmetricEncryption::Reader.open(@filename) do |file|
|
94
|
+
i = 0
|
95
|
+
file.each_line do |line|
|
96
|
+
assert_equal @data[i], line
|
97
|
+
i += 1
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
72
103
|
|
73
104
|
end
|
74
105
|
end
|
75
|
-
|
76
|
-
end
|
106
|
+
end
|
data/test/writer_test.rb
CHANGED
@@ -25,6 +25,10 @@ class EncryptionWriterTest < Test::Unit::TestCase
|
|
25
25
|
@filename = '._test'
|
26
26
|
end
|
27
27
|
|
28
|
+
teardown do
|
29
|
+
File.delete(@filename) if File.exist?(@filename)
|
30
|
+
end
|
31
|
+
|
28
32
|
should "encrypt to string stream" do
|
29
33
|
stream = StringIO.new
|
30
34
|
file = SymmetricEncryption::Writer.new(stream)
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 6
|
8
|
+
- 0
|
9
|
+
version: 0.6.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Reid Morrison
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-04-
|
17
|
+
date: 2012-04-30 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -49,10 +49,6 @@ files:
|
|
49
49
|
- nbproject/project.xml
|
50
50
|
- Rakefile
|
51
51
|
- README.md
|
52
|
-
- symmetric-encryption-0.2.0.gem
|
53
|
-
- symmetric-encryption-0.4.0.gem
|
54
|
-
- symmetric-encryption-0.5.0.gem
|
55
|
-
- symmetric-encryption-0.5.1.gem
|
56
52
|
- test/attr_encrypted_test.rb
|
57
53
|
- test/cipher_test.rb
|
58
54
|
- test/config/database.yml
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|