symmetric-encryption 0.4.0 → 0.5.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/README.md +41 -11
- data/Rakefile +3 -3
- data/lib/symmetric-encryption.rb +10 -7
- data/lib/symmetric_encryption/cipher.rb +114 -0
- data/lib/{symmetric → symmetric_encryption}/extensions/active_record/base.rb +4 -7
- data/lib/{symmetric → symmetric_encryption}/extensions/mongoid/fields.rb +19 -10
- data/lib/{symmetric → symmetric_encryption}/railtie.rb +4 -4
- data/lib/{symmetric → symmetric_encryption}/railties/symmetric_encryption.rake +5 -5
- data/lib/{symmetric/railties/symmetric_encrypted_validator.rb → symmetric_encryption/railties/symmetric_encryption_validator.rb} +4 -4
- data/lib/symmetric_encryption/reader.rb +221 -0
- data/lib/symmetric_encryption/symmetric_encryption.rb +280 -0
- data/lib/symmetric_encryption/version.rb +4 -0
- data/lib/symmetric_encryption/writer.rb +132 -0
- data/nbproject/private/private.xml +14 -1
- data/symmetric-encryption-0.2.0.gem +0 -0
- data/symmetric-encryption-0.4.0.gem +0 -0
- data/test/attr_encrypted_test.rb +7 -7
- data/test/cipher_test.rb +8 -13
- data/test/field_encrypted_test.rb +3 -3
- data/test/reader_test.rb +76 -0
- data/test/symmetric_encryption_test.rb +53 -0
- data/test/writer_test.rb +56 -0
- metadata +20 -15
- data/lib/symmetric/cipher.rb +0 -184
- data/lib/symmetric/encryption.rb +0 -262
- data/lib/symmetric/version.rb +0 -4
- data/symmetric-encryption-0.3.0.gem +0 -0
- data/symmetric-encryption-0.3.1.gem +0 -0
- data/test/encryption_test.rb +0 -51
@@ -0,0 +1,132 @@
|
|
1
|
+
module SymmetricEncryption
|
2
|
+
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
|
+
# Open a file for writing, or use the supplied IO Stream
|
28
|
+
#
|
29
|
+
# Parameters:
|
30
|
+
# filename_or_stream:
|
31
|
+
# The filename to open if a string, otherwise the stream to use
|
32
|
+
# The file or stream will be closed on completion, use .initialize to
|
33
|
+
# avoid having the stream closed automatically
|
34
|
+
#
|
35
|
+
# options:
|
36
|
+
# :compress [true|false]
|
37
|
+
# Uses Zlib to compress the data before it is encrypted and
|
38
|
+
# written to the file
|
39
|
+
# Default: false
|
40
|
+
#
|
41
|
+
# :header [true|false]
|
42
|
+
# Whether to include the magic header that indicates the file
|
43
|
+
# is encrypted and whether its contents are compressed
|
44
|
+
#
|
45
|
+
# The header contains:
|
46
|
+
# Version of the encryption key used to encrypt the file
|
47
|
+
# Indicator if the data was compressed
|
48
|
+
# Default: false
|
49
|
+
#
|
50
|
+
# :version
|
51
|
+
# Version of the encryption key to use when encrypting
|
52
|
+
# Default: Current primary key
|
53
|
+
#
|
54
|
+
# :mode
|
55
|
+
# See File.open for open modes
|
56
|
+
# Default: 'w'
|
57
|
+
#
|
58
|
+
# Note: Compression occurs before encryption
|
59
|
+
#
|
60
|
+
def self.open(filename_or_stream, options={}, &block)
|
61
|
+
raise "options must be a hash" unless options.respond_to?(:each_pair)
|
62
|
+
mode = options.fetch(:mode, 'w')
|
63
|
+
compress = options.fetch(:compress, false)
|
64
|
+
ios = filename_or_stream.is_a?(String) ? ::File.open(filename_or_stream, mode) : filename_or_stream
|
65
|
+
|
66
|
+
begin
|
67
|
+
file = self.new(ios, options)
|
68
|
+
file = Zlib::GzipWriter.new(file) if compress
|
69
|
+
block.call(file)
|
70
|
+
ensure
|
71
|
+
file.close if file
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Encrypt data before writing to the supplied stream
|
76
|
+
def initialize(ios,options={})
|
77
|
+
@ios = ios
|
78
|
+
header = options.fetch(:header, false)
|
79
|
+
# Compress is only used at this point for setting the flag in the header
|
80
|
+
@compress = options.fetch(:compress, false)
|
81
|
+
|
82
|
+
# Use primary cipher by default, but allow a secondary cipher to be selected for encryption
|
83
|
+
@cipher = SymmetricEncryption.cipher(options[:version])
|
84
|
+
raise "Cipher with version:#{options[:version]} not found in any of the configured SymmetricEncryption ciphers" unless @cipher
|
85
|
+
|
86
|
+
@stream_cipher = @cipher.send(:openssl_cipher, :encrypt)
|
87
|
+
|
88
|
+
write_header if header
|
89
|
+
end
|
90
|
+
|
91
|
+
# Close the IO Stream
|
92
|
+
# Flushes any unwritten data
|
93
|
+
#
|
94
|
+
# Note: Once an EncryptionWriter has been closed a new instance must be
|
95
|
+
# created before writing again
|
96
|
+
#
|
97
|
+
# Note: Also closes the passed in io stream or file
|
98
|
+
# Note: This method must be called _before_ the supplied stream is closed
|
99
|
+
#
|
100
|
+
# It is recommended to call Symmetric::EncryptedStream.open
|
101
|
+
# rather than creating an instance of Symmetric::EncryptedStream directly to
|
102
|
+
# ensure that the encrypted stream is closed before the stream itself is closed
|
103
|
+
def close(close_child_stream = true)
|
104
|
+
final = @stream_cipher.final
|
105
|
+
@ios.write(final) if final.length > 0
|
106
|
+
@ios.close if close_child_stream
|
107
|
+
end
|
108
|
+
|
109
|
+
# Write to the IO Stream as encrypted data
|
110
|
+
# Returns the number of bytes written
|
111
|
+
def write(data)
|
112
|
+
partial = @stream_cipher.update(data.to_s)
|
113
|
+
@ios.write(partial) if partial.length > 0
|
114
|
+
data.length
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
# Write the Encryption header if this is the first write
|
120
|
+
def write_header
|
121
|
+
# Include Header and encryption version indicator
|
122
|
+
flags = @cipher.version || 0 # Same as 0b0000_0000_0000_0000
|
123
|
+
|
124
|
+
# If the data is to be compressed before being encrypted, set the
|
125
|
+
# compressed bit in the version byte
|
126
|
+
flags |= 0b1000_0000_0000_0000 if @compress
|
127
|
+
|
128
|
+
@ios.write "#{MAGIC_HEADER}#{[flags].pack('v')}"
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
@@ -1,4 +1,17 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
3
|
-
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"
|
3
|
+
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1">
|
4
|
+
<file>
|
5
|
+
<url>lib/symmetric_encryption/encryption.rb</url>
|
6
|
+
<line>60</line>
|
7
|
+
</file>
|
8
|
+
<file>
|
9
|
+
<url>lib/symmetric/encryption.rb</url>
|
10
|
+
<line>62</line>
|
11
|
+
</file>
|
12
|
+
<file>
|
13
|
+
<url>lib/symmetric_encryption/symmetric_encryption.rb</url>
|
14
|
+
<line>60</line>
|
15
|
+
</file>
|
16
|
+
</editor-bookmarks>
|
4
17
|
</project-private>
|
Binary file
|
Binary file
|
data/test/attr_encrypted_test.rb
CHANGED
@@ -27,12 +27,12 @@ class User < ActiveRecord::Base
|
|
27
27
|
attr_encrypted :bank_account_number
|
28
28
|
attr_encrypted :social_security_number
|
29
29
|
|
30
|
-
validates :encrypted_bank_account_number, :
|
31
|
-
validates :encrypted_social_security_number, :
|
30
|
+
validates :encrypted_bank_account_number, :symmetric_encryption => true
|
31
|
+
validates :encrypted_social_security_number, :symmetric_encryption => true
|
32
32
|
end
|
33
33
|
|
34
34
|
# Load Symmetric Encryption keys
|
35
|
-
|
35
|
+
SymmetricEncryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
|
36
36
|
|
37
37
|
# Initialize the database connection
|
38
38
|
config_file = File.join(File.dirname(__FILE__), 'config', 'database.yml')
|
@@ -44,10 +44,10 @@ raise("Environment 'test' not defined in test/config/database.yml") unless cfg
|
|
44
44
|
User.establish_connection(cfg)
|
45
45
|
|
46
46
|
#
|
47
|
-
# Unit Test for attr_encrypted and validation aspects of
|
47
|
+
# Unit Test for attr_encrypted and validation aspects of SymmetricEncryption
|
48
48
|
#
|
49
49
|
class AttrEncryptedTest < Test::Unit::TestCase
|
50
|
-
context 'the
|
50
|
+
context 'the SymmetricEncryption Library' do
|
51
51
|
|
52
52
|
setup do
|
53
53
|
@bank_account_number = "1234567890"
|
@@ -159,8 +159,8 @@ class AttrEncryptedTest < Test::Unit::TestCase
|
|
159
159
|
assert_equal true, @user.valid?
|
160
160
|
@user.encrypted_bank_account_number = '123'
|
161
161
|
assert_equal false, @user.valid?
|
162
|
-
assert_equal ["must be a value encrypted using
|
163
|
-
@user.encrypted_bank_account_number =
|
162
|
+
assert_equal ["must be a value encrypted using SymmetricEncryption.encrypt"], @user.errors[:encrypted_bank_account_number]
|
163
|
+
@user.encrypted_bank_account_number = SymmetricEncryption.encrypt('123')
|
164
164
|
assert_equal true, @user.valid?
|
165
165
|
@user.bank_account_number = '123'
|
166
166
|
assert_equal true, @user.valid?
|
data/test/cipher_test.rb
CHANGED
@@ -4,15 +4,15 @@ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
|
4
4
|
require 'rubygems'
|
5
5
|
require 'test/unit'
|
6
6
|
require 'shoulda'
|
7
|
-
require '
|
7
|
+
require 'symmetric_encryption/cipher'
|
8
8
|
|
9
|
-
# Unit Test for
|
9
|
+
# Unit Test for SymmetricEncryption::Cipher
|
10
10
|
#
|
11
11
|
class CipherTest < Test::Unit::TestCase
|
12
12
|
context 'standalone' do
|
13
13
|
|
14
14
|
should "allow setting the cipher" do
|
15
|
-
cipher =
|
15
|
+
cipher = SymmetricEncryption::Cipher.new(
|
16
16
|
:cipher => 'aes-128-cbc',
|
17
17
|
:key => '1234567890ABCDEF1234567890ABCDEF',
|
18
18
|
:iv => '1234567890ABCDEF'
|
@@ -21,14 +21,14 @@ class CipherTest < Test::Unit::TestCase
|
|
21
21
|
end
|
22
22
|
|
23
23
|
should "not require an iv" do
|
24
|
-
cipher =
|
24
|
+
cipher = SymmetricEncryption::Cipher.new(
|
25
25
|
:key => '1234567890ABCDEF1234567890ABCDEF'
|
26
26
|
)
|
27
|
-
assert_equal "
|
27
|
+
assert_equal "\302<\351\227oj\372\3331\310\260V\001\v'\346", cipher.encrypt('Hello World')
|
28
28
|
end
|
29
29
|
|
30
30
|
should "throw an exception on bad data" do
|
31
|
-
cipher =
|
31
|
+
cipher = SymmetricEncryption::Cipher.new(
|
32
32
|
:cipher => 'aes-128-cbc',
|
33
33
|
:key => '1234567890ABCDEF1234567890ABCDEF',
|
34
34
|
:iv => '1234567890ABCDEF'
|
@@ -42,12 +42,12 @@ class CipherTest < Test::Unit::TestCase
|
|
42
42
|
|
43
43
|
context 'with configuration' do
|
44
44
|
setup do
|
45
|
-
@cipher =
|
45
|
+
@cipher = SymmetricEncryption::Cipher.new(
|
46
46
|
:key => '1234567890ABCDEF1234567890ABCDEF',
|
47
47
|
:iv => '1234567890ABCDEF'
|
48
48
|
)
|
49
49
|
@social_security_number = "987654321"
|
50
|
-
@social_security_number_encrypted = "
|
50
|
+
@social_security_number_encrypted = "A\335*\314\336\250V\340\023%\000S\177\305\372\266"
|
51
51
|
@sample_data = [
|
52
52
|
{ :text => '555052345', :encrypted => ''}
|
53
53
|
]
|
@@ -65,10 +65,5 @@ class CipherTest < Test::Unit::TestCase
|
|
65
65
|
assert_equal @social_security_number, @cipher.decrypt(@social_security_number_encrypted)
|
66
66
|
end
|
67
67
|
|
68
|
-
should "determine if string is encrypted" do
|
69
|
-
assert_equal true, @cipher.encrypted?(@social_security_number_encrypted)
|
70
|
-
assert_equal false, @cipher.encrypted?(@social_security_number)
|
71
|
-
end
|
72
|
-
|
73
68
|
end
|
74
69
|
end
|
@@ -30,13 +30,13 @@ class MongoidUser
|
|
30
30
|
end
|
31
31
|
|
32
32
|
# Load Symmetric Encryption keys
|
33
|
-
|
33
|
+
SymmetricEncryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
|
34
34
|
|
35
35
|
#
|
36
|
-
# Unit Tests for field encrypted and validation aspects of
|
36
|
+
# Unit Tests for field encrypted and validation aspects of SymmetricEncryption
|
37
37
|
#
|
38
38
|
class FieldEncryptedTest < Test::Unit::TestCase
|
39
|
-
context 'the
|
39
|
+
context 'the SymmetricEncryption Library' do
|
40
40
|
setup do
|
41
41
|
@bank_account_number = "1234567890"
|
42
42
|
@bank_account_number_encrypted = "L94ArJeFlJrZp6SYsvoOGA==\n"
|
data/test/reader_test.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Allow examples to be run in-place without requiring a gem install
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'test/unit'
|
6
|
+
require 'shoulda'
|
7
|
+
require 'symmetric-encryption'
|
8
|
+
|
9
|
+
# Load Symmetric Encryption keys
|
10
|
+
SymmetricEncryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
|
11
|
+
|
12
|
+
# Unit Test for SymmetricEncrypted::ReaderStream
|
13
|
+
#
|
14
|
+
class ReaderTest < Test::Unit::TestCase
|
15
|
+
context 'Reader' do
|
16
|
+
setup do
|
17
|
+
@data = [
|
18
|
+
"Hello World\n",
|
19
|
+
"Keep this secret\n",
|
20
|
+
"And keep going even further and further..."
|
21
|
+
]
|
22
|
+
@data_str = @data.inject('') {|sum,str| sum << str}
|
23
|
+
@data_len = @data_str.length
|
24
|
+
@data_encrypted = SymmetricEncryption.cipher.encrypt(@data_str)
|
25
|
+
@filename = '._test'
|
26
|
+
end
|
27
|
+
|
28
|
+
should "decrypt from string stream as a single read" do
|
29
|
+
stream = StringIO.new(@data_encrypted)
|
30
|
+
decrypted = SymmetricEncryption::Reader.open(stream) {|file| file.read}
|
31
|
+
assert_equal @data_str, decrypted
|
32
|
+
end
|
33
|
+
|
34
|
+
should "decrypt from string stream as a single read, after a partial read" do
|
35
|
+
stream = StringIO.new(@data_encrypted)
|
36
|
+
decrypted = SymmetricEncryption::Reader.open(stream) do |file|
|
37
|
+
file.read(10)
|
38
|
+
file.read
|
39
|
+
end
|
40
|
+
assert_equal @data_str[10..-1], decrypted
|
41
|
+
end
|
42
|
+
|
43
|
+
should "decrypt lines from string stream" do
|
44
|
+
stream = StringIO.new(@data_encrypted)
|
45
|
+
i = 0
|
46
|
+
decrypted = SymmetricEncryption::Reader.open(stream) do |file|
|
47
|
+
file.each_line do |line|
|
48
|
+
assert_equal @data[i], line
|
49
|
+
i += 1
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
should "decrypt fixed lengths from string stream" do
|
55
|
+
stream = StringIO.new(@data_encrypted)
|
56
|
+
i = 0
|
57
|
+
SymmetricEncryption::Reader.open(stream) do |file|
|
58
|
+
index = 0
|
59
|
+
[0,10,5,5000].each do |size|
|
60
|
+
buf = file.read(size)
|
61
|
+
if size == 0
|
62
|
+
assert_equal '', buf
|
63
|
+
else
|
64
|
+
assert_equal @data_str[index..index+size-1], buf
|
65
|
+
end
|
66
|
+
index += size
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
should "decrypt from file" do
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Allow examples to be run in-place without requiring a gem install
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'test/unit'
|
6
|
+
require 'shoulda'
|
7
|
+
require 'symmetric-encryption'
|
8
|
+
|
9
|
+
# Load Symmetric Encryption keys
|
10
|
+
SymmetricEncryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
|
11
|
+
|
12
|
+
# Unit Test for SymmetricEncryption
|
13
|
+
#
|
14
|
+
class SymmetricEncryptionTest < Test::Unit::TestCase
|
15
|
+
context 'initialized' do
|
16
|
+
|
17
|
+
context 'SymmetricEncryption configuration' do
|
18
|
+
setup do
|
19
|
+
@config = SymmetricEncryption.send(:read_config, File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
|
20
|
+
end
|
21
|
+
|
22
|
+
should "match config file" do
|
23
|
+
assert_equal @config[:ciphers][0][:cipher], SymmetricEncryption.cipher.cipher
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'SymmetricEncryption tests' do
|
28
|
+
setup do
|
29
|
+
@social_security_number = "987654321"
|
30
|
+
@social_security_number_encrypted = "S+8X1NRrqdfEIQyFHVPuVA==\n"
|
31
|
+
@social_security_number_encrypted_with_secondary_1 = "D1UCu38pqJ3jc0GvwJHiow==\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
should "encrypt simple string" do
|
35
|
+
assert_equal @social_security_number_encrypted, SymmetricEncryption.encrypt(@social_security_number)
|
36
|
+
end
|
37
|
+
|
38
|
+
should "decrypt string" do
|
39
|
+
assert_equal @social_security_number, SymmetricEncryption.decrypt(@social_security_number_encrypted)
|
40
|
+
end
|
41
|
+
|
42
|
+
should "determine if string is encrypted" do
|
43
|
+
assert_equal true, SymmetricEncryption.encrypted?(@social_security_number_encrypted)
|
44
|
+
assert_equal false, SymmetricEncryption.encrypted?(@social_security_number)
|
45
|
+
end
|
46
|
+
|
47
|
+
should "decrypt with secondary key when first one fails" do
|
48
|
+
assert_equal @social_security_number, SymmetricEncryption.decrypt(@social_security_number_encrypted)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/test/writer_test.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Allow examples to be run in-place without requiring a gem install
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'test/unit'
|
6
|
+
require 'shoulda'
|
7
|
+
require 'symmetric-encryption'
|
8
|
+
|
9
|
+
# Load Symmetric Encryption keys
|
10
|
+
SymmetricEncryption.load!(File.join(File.dirname(__FILE__), 'config', 'symmetric-encryption.yml'), 'test')
|
11
|
+
|
12
|
+
# Unit Test for Symmetric::EncryptedStream
|
13
|
+
#
|
14
|
+
class EncryptionWriterTest < Test::Unit::TestCase
|
15
|
+
context 'EncryptionWriter' do
|
16
|
+
setup do
|
17
|
+
@data = [
|
18
|
+
"Hello World\n",
|
19
|
+
"Keep this secret\n",
|
20
|
+
"And keep going even further and further..."
|
21
|
+
]
|
22
|
+
@data_str = @data.inject('') {|sum,str| sum << str}
|
23
|
+
@data_len = @data_str.length
|
24
|
+
@data_encrypted = SymmetricEncryption.cipher.encrypt(@data_str)
|
25
|
+
@filename = '._test'
|
26
|
+
end
|
27
|
+
|
28
|
+
should "encrypt to string stream" do
|
29
|
+
stream = StringIO.new
|
30
|
+
file = SymmetricEncryption::Writer.new(stream)
|
31
|
+
written_len = @data.inject(0) {|sum,str| sum + file.write(str)}
|
32
|
+
file.close
|
33
|
+
|
34
|
+
assert_equal @data_len, written_len
|
35
|
+
assert_equal @data_encrypted, stream.string
|
36
|
+
end
|
37
|
+
|
38
|
+
should "encrypt to string stream using .open" do
|
39
|
+
written_len = 0
|
40
|
+
stream = StringIO.new
|
41
|
+
SymmetricEncryption::Writer.open(stream) do |file|
|
42
|
+
written_len = @data.inject(0) {|sum,str| sum + file.write(str)}
|
43
|
+
end
|
44
|
+
assert_equal @data_len, written_len
|
45
|
+
end
|
46
|
+
|
47
|
+
should "encrypt to file using .open" do
|
48
|
+
written_len = nil
|
49
|
+
SymmetricEncryption::Writer.open(@filename) do |file|
|
50
|
+
written_len = @data.inject(0) {|sum,str| sum + file.write(str)}
|
51
|
+
end
|
52
|
+
assert_equal @data_len, written_len
|
53
|
+
assert_equal @data_encrypted, File.read(@filename)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|