symmetric-encryption 1.1.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +75 -23
- data/lib/rails/generators/symmetric_encryption/config/templates/symmetric-encryption.yml +7 -6
- data/lib/symmetric_encryption/cipher.rb +161 -126
- data/lib/symmetric_encryption/extensions/active_record/base.rb +36 -13
- data/lib/symmetric_encryption/extensions/mongoid/fields.rb +23 -12
- data/lib/symmetric_encryption/railtie.rb +4 -4
- data/lib/symmetric_encryption/reader.rb +7 -5
- data/lib/symmetric_encryption/symmetric_encryption.rb +54 -24
- data/lib/symmetric_encryption/version.rb +1 -1
- data/lib/symmetric_encryption/writer.rb +61 -15
- data/test/attr_encrypted_test.rb +30 -0
- data/test/cipher_test.rb +14 -13
- data/test/config/symmetric-encryption.yml +2 -2
- data/test/field_encrypted_test.rb +28 -0
- data/test/reader_test.rb +72 -38
- data/test/symmetric_encryption_test.rb +25 -5
- data/test/test_db.sqlite3 +0 -0
- data/test/writer_test.rb +3 -3
- metadata +2 -2
@@ -2,26 +2,49 @@ module ActiveRecord #:nodoc:
|
|
2
2
|
class Base
|
3
3
|
|
4
4
|
class << self # Class methods
|
5
|
-
#
|
6
|
-
#
|
5
|
+
# Drop in replacement for attr_encrypted gem, except that it uses
|
6
|
+
# SymmetricEncryption for managing the encryption key
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# Params:
|
12
|
-
# * symbolic names of each method to create which has a corresponding
|
8
|
+
# Parameters:
|
9
|
+
# * Symbolic names of each method to create which has a corresponding
|
13
10
|
# method already defined in rails starting with: encrypted_
|
14
|
-
# * Followed by an
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
11
|
+
# * Followed by an optional hash:
|
12
|
+
# :marshal [true|false]
|
13
|
+
# Whether this element should be converted to YAML before encryption
|
14
|
+
# Default: false
|
15
|
+
#
|
16
|
+
# :random_iv [true|false]
|
17
|
+
# Whether the encrypted value should use a random IV every time the
|
18
|
+
# field is encrypted.
|
19
|
+
# It is recommended to set this to true where feasible. If the encrypted
|
20
|
+
# value could be used as part of a SQL where clause, or as part
|
21
|
+
# of any lookup, then it must be false.
|
22
|
+
# Setting random_iv to true will result in a different encrypted output for
|
23
|
+
# the same input string.
|
24
|
+
# Note: Only set to true if the field will never be used as part of
|
25
|
+
# the where clause in an SQL query.
|
26
|
+
# Note: When random_iv is true it will add a 8 byte header, plus the bytes
|
27
|
+
# to store the random IV in every returned encrypted string, prior to the
|
28
|
+
# encoding if any.
|
29
|
+
# Default: false
|
30
|
+
# Highly Recommended where feasible: true
|
31
|
+
#
|
32
|
+
# :compress [true|false]
|
33
|
+
# Whether to compress str before encryption
|
34
|
+
# Should only be used for large strings since compression overhead and
|
35
|
+
# the overhead of adding the 'magic' header may exceed any benefits of
|
36
|
+
# compression
|
37
|
+
# Note: Adds a 6 byte header prior to encoding, only if :random_iv is false
|
38
|
+
# Default: false
|
19
39
|
def attr_encrypted(*params)
|
20
40
|
# Ensure ActiveRecord has created all its methods first
|
21
41
|
# Ignore failures since the table may not yet actually exist
|
22
42
|
define_attribute_methods rescue nil
|
23
43
|
|
24
44
|
options = params.last.is_a?(Hash) ? params.pop : {}
|
45
|
+
random_iv = options.fetch(:random_iv, false)
|
46
|
+
compress = options.fetch(:compress, false)
|
47
|
+
marshal = options.fetch(:marshal, false)
|
25
48
|
|
26
49
|
params.each do |attribute|
|
27
50
|
# Generate unencrypted attribute with getter and setter
|
@@ -40,7 +63,7 @@ module ActiveRecord #:nodoc:
|
|
40
63
|
# Set the un-encrypted attribute
|
41
64
|
# Also updates the encrypted field with the encrypted value
|
42
65
|
def #{attribute}=(value)
|
43
|
-
self.encrypted_#{attribute} = @stored_encrypted_#{attribute} = ::SymmetricEncryption.encrypt(value#{".to_yaml" if
|
66
|
+
self.encrypted_#{attribute} = @stored_encrypted_#{attribute} = ::SymmetricEncryption.encrypt(value#{".to_yaml" if marshal},#{random_iv},#{compress})
|
44
67
|
@#{attribute} = value
|
45
68
|
end
|
46
69
|
UNENCRYPTED
|
@@ -25,6 +25,7 @@ module Mongoid
|
|
25
25
|
# field :name, :type => String
|
26
26
|
# field :encrypted_social_security_number, :type => String, :encrypted => true
|
27
27
|
# field :age, :type => Integer
|
28
|
+
# field :life_history, :type => String, :encrypted => true, :compress => true, :random_iv => true
|
28
29
|
#
|
29
30
|
# end
|
30
31
|
#
|
@@ -50,28 +51,35 @@ module Mongoid
|
|
50
51
|
# person.social_security_number = "123456789"
|
51
52
|
#
|
52
53
|
# # Or, is equivalent to:
|
53
|
-
# person.
|
54
|
+
# person.encrypted_social_security_number = SymmetricEncryption.encrypt("123456789")
|
54
55
|
#
|
55
56
|
#
|
56
57
|
# Note: Unlike attr_encrypted finders must use the encrypted field name
|
57
|
-
#
|
58
|
+
# Invalid Example, does not work:
|
58
59
|
# person = Person.where(:social_security_number => '123456789').first
|
59
60
|
#
|
61
|
+
# Valid Example:
|
62
|
+
# person = Person.where(:encrypted_social_security_number => SymmetricEncryption.encrypt('123456789')).first
|
63
|
+
#
|
60
64
|
# Defines all the fields that are accessible on the Document
|
61
65
|
# For each field that is defined, a getter and setter will be
|
62
66
|
# added as an instance method to the Document.
|
63
67
|
#
|
64
68
|
# @example Define a field.
|
65
|
-
# field :
|
69
|
+
# field :social_security_number, :type => String, :encrypted => true, :compress => false, :random_iv => false
|
70
|
+
# field :sensitive_text, :type => String, :encrypted => true, :compress => true, :random_iv => true
|
66
71
|
#
|
67
72
|
# @param [ Symbol ] name The name of the field.
|
68
73
|
# @param [ Hash ] options The options to pass to the field.
|
69
74
|
#
|
70
|
-
# @option options [ Boolean ] :
|
71
|
-
# @option options [ Symbol ]
|
72
|
-
# @option options [
|
73
|
-
# @option options [
|
74
|
-
#
|
75
|
+
# @option options [ Boolean ] :encrypted If the field contains encrypted data.
|
76
|
+
# @option options [ Symbol ] :decrypt_as Name of the getters and setters to generate to access the decrypted value of this field.
|
77
|
+
# @option options [ Boolean ] :compress Whether to compress this encrypted field
|
78
|
+
# @option options [ Boolean ] :random_iv Whether the encrypted value should use a random IV every time the field is encrypted.
|
79
|
+
#
|
80
|
+
# @option options [ Class ] :type The type of the field.
|
81
|
+
# @option options [ String ] :label The label for the field.
|
82
|
+
# @option options [ Object, Proc ] :default The fields default
|
75
83
|
#
|
76
84
|
# @return [ Field ] The generated field
|
77
85
|
def field_with_symmetric_encryption(field_name, options={})
|
@@ -82,20 +90,23 @@ module Mongoid
|
|
82
90
|
decrypt_as = field_name.to_s['encrypted_'.length..-1]
|
83
91
|
end
|
84
92
|
|
93
|
+
random_iv = options.delete(:random_iv) || false
|
94
|
+
compress = options.delete(:compress) || false
|
95
|
+
|
85
96
|
# Store Intended data type for this field, but we store it as a String
|
86
97
|
underlying_type = options[:type]
|
87
98
|
options[:type] = String
|
88
99
|
|
89
100
|
raise "SymmetricEncryption for Mongoid currently only supports :type => String" unless underlying_type == String
|
90
101
|
|
91
|
-
# #TODO Need to do type conversions. Currently only
|
102
|
+
# #TODO Need to do type conversions. Currently only supports String
|
92
103
|
|
93
104
|
# Generate getter and setter methods
|
94
105
|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
95
|
-
# Set the un-encrypted
|
106
|
+
# Set the un-encrypted field
|
96
107
|
# Also updates the encrypted field with the encrypted value
|
97
108
|
def #{decrypt_as}=(value)
|
98
|
-
@stored_#{field_name} = SymmetricEncryption.encrypt(value)
|
109
|
+
@stored_#{field_name} = ::SymmetricEncryption.encrypt(value,#{random_iv},#{compress})
|
99
110
|
self.#{field_name} = @stored_#{field_name}
|
100
111
|
@#{decrypt_as} = value
|
101
112
|
end
|
@@ -105,7 +116,7 @@ module Mongoid
|
|
105
116
|
# If this method is not called, then the encrypted value is never decrypted
|
106
117
|
def #{decrypt_as}
|
107
118
|
if @stored_#{field_name} != self.#{field_name}
|
108
|
-
@#{decrypt_as} = SymmetricEncryption.decrypt(self.#{field_name})
|
119
|
+
@#{decrypt_as} = ::SymmetricEncryption.decrypt(self.#{field_name})
|
109
120
|
@stored_#{field_name} = self.#{field_name}
|
110
121
|
end
|
111
122
|
@#{decrypt_as}
|
@@ -10,7 +10,7 @@ module SymmetricEncryption #:nodoc:
|
|
10
10
|
# config.symmetric_encryption.cipher = SymmetricEncryption::Cipher.new(
|
11
11
|
# :key => '1234567890ABCDEF1234567890ABCDEF',
|
12
12
|
# :iv => '1234567890ABCDEF',
|
13
|
-
# :
|
13
|
+
# :cipher_name => 'aes-128-cbc'
|
14
14
|
# )
|
15
15
|
# end
|
16
16
|
# end
|
@@ -26,9 +26,9 @@ module SymmetricEncryption #:nodoc:
|
|
26
26
|
# @example symmetric-encryption.yml
|
27
27
|
#
|
28
28
|
# development:
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
29
|
+
# cipher_name: aes-256-cbc
|
30
|
+
# key: 1234567890ABCDEF1234567890ABCDEF
|
31
|
+
# iv: 1234567890ABCDEF
|
32
32
|
#
|
33
33
|
# Loaded before Active Record initializes since database.yml can have encrypted
|
34
34
|
# passwords in it
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
1
3
|
module SymmetricEncryption
|
2
4
|
# Read from encrypted files and other IO streams
|
3
5
|
#
|
@@ -293,12 +295,12 @@ module SymmetricEncryption
|
|
293
295
|
buf = @ios.read(@buffer_size)
|
294
296
|
|
295
297
|
# Use cipher specified in header, or global cipher if it has no header
|
296
|
-
@
|
297
|
-
|
298
|
-
# Use supplied version if cipher could not be detected due to missing header
|
299
|
-
@cipher ||= SymmetricEncryption.cipher(@version)
|
298
|
+
@compressed, iv, key, cipher_name, decryption_cipher = SymmetricEncryption::Cipher.parse_magic_header!(buf, @version)
|
300
299
|
|
301
|
-
@stream_cipher =
|
300
|
+
@stream_cipher = ::OpenSSL::Cipher.new(cipher_name || decryption_cipher.cipher_name)
|
301
|
+
@stream_cipher.decrypt
|
302
|
+
@stream_cipher.key = key || decryption_cipher.send(:key)
|
303
|
+
@stream_cipher.iv = iv || decryption_cipher.send(:iv)
|
302
304
|
|
303
305
|
# First call to #update should return an empty string anyway
|
304
306
|
@read_buffer = @stream_cipher.update(buf)
|
@@ -85,11 +85,40 @@ module SymmetricEncryption
|
|
85
85
|
# Returns result as a Base64 encoded string
|
86
86
|
# Returns nil if the supplied str is nil
|
87
87
|
# Returns "" if it is a string and it is empty
|
88
|
-
|
88
|
+
#
|
89
|
+
# Parameters
|
90
|
+
# str [String]
|
91
|
+
# String to be encrypted. If str is not a string, #to_s will be called on it
|
92
|
+
# to convert it to a string
|
93
|
+
#
|
94
|
+
# random_iv [true|false]
|
95
|
+
# Whether the encypted value should use a random IV every time the
|
96
|
+
# field is encrypted.
|
97
|
+
# It is recommended to set this to true where feasible. If the encrypted
|
98
|
+
# value could be used as part of a SQL where clause, or as part
|
99
|
+
# of any lookup, then it must be false.
|
100
|
+
# Setting random_iv to true will result in a different encrypted output for
|
101
|
+
# the same input string.
|
102
|
+
# Note: Only set to true if the field will never be used as part of
|
103
|
+
# the where clause in an SQL query.
|
104
|
+
# Note: When random_iv is true it will add a 8 byte header, plus the bytes
|
105
|
+
# to store the random IV in every returned encrypted string, prior to the
|
106
|
+
# encoding if any.
|
107
|
+
# Default: false
|
108
|
+
# Highly Recommended where feasible: true
|
109
|
+
#
|
110
|
+
# compress [true|false]
|
111
|
+
# Whether to compress str before encryption
|
112
|
+
# Should only be used for large strings since compression overhead and
|
113
|
+
# the overhead of adding the 'magic' header may exceed any benefits of
|
114
|
+
# compression
|
115
|
+
# Note: Adds a 6 byte header prior to encoding, only if :random_iv is false
|
116
|
+
# Default: false
|
117
|
+
def self.encrypt(str, random_iv=false, compress=false)
|
89
118
|
raise "Call SymmetricEncryption.load! or SymmetricEncryption.cipher= prior to encrypting or decrypting data" unless @@cipher
|
90
119
|
|
91
120
|
# Encrypt and then encode the supplied string
|
92
|
-
@@cipher.encrypt(str)
|
121
|
+
@@cipher.encrypt(str, random_iv, compress)
|
93
122
|
end
|
94
123
|
|
95
124
|
# Invokes decrypt
|
@@ -159,13 +188,13 @@ module SymmetricEncryption
|
|
159
188
|
cipher_cfg = config[:ciphers].first
|
160
189
|
key_filename = cipher_cfg[:key_filename]
|
161
190
|
iv_filename = cipher_cfg[:iv_filename]
|
162
|
-
|
191
|
+
cipher_name = cipher_cfg[:cipher_name] || cipher_cfg[:cipher]
|
163
192
|
|
164
193
|
raise "The configuration file must contain a 'private_rsa_key' parameter to generate symmetric keys" unless config[:private_rsa_key]
|
165
194
|
rsa_key = OpenSSL::PKey::RSA.new(config[:private_rsa_key])
|
166
195
|
|
167
196
|
# Generate a new Symmetric Key pair
|
168
|
-
key_pair = SymmetricEncryption::Cipher.random_key_pair(
|
197
|
+
key_pair = SymmetricEncryption::Cipher.random_key_pair(cipher_name || 'aes-256-cbc', !iv_filename.nil?)
|
169
198
|
|
170
199
|
# Save symmetric key after encrypting it with the private RSA key, backing up existing files if present
|
171
200
|
File.rename(key_filename, "#{key_filename}.#{Time.now.to_i}") if File.exist?(key_filename)
|
@@ -207,15 +236,15 @@ module SymmetricEncryption
|
|
207
236
|
config = YAML.load_file(filename || File.join(Rails.root, "config", "symmetric-encryption.yml"))[environment || Rails.env]
|
208
237
|
|
209
238
|
# Default cipher
|
210
|
-
default_cipher = config['cipher'] || 'aes-256-cbc'
|
239
|
+
default_cipher = config['cipher_name'] || config['cipher'] || 'aes-256-cbc'
|
211
240
|
cfg = {}
|
212
241
|
|
213
242
|
# Hard coded symmetric_key? - Dev / Testing use only!
|
214
243
|
if symmetric_key = (config['key'] || config['symmetric_key'])
|
215
244
|
raise "SymmetricEncryption Cannot hard code Production encryption keys in #{filename}" if (environment || Rails.env) == 'production'
|
216
|
-
cfg[:key]
|
217
|
-
cfg[:iv]
|
218
|
-
cfg[:
|
245
|
+
cfg[:key] = symmetric_key
|
246
|
+
cfg[:iv] = config['iv'] || config['symmetric_iv']
|
247
|
+
cfg[:cipher_name] = default_cipher
|
219
248
|
|
220
249
|
elsif ciphers = config['ciphers']
|
221
250
|
raise "Missing mandatory config parameter 'private_rsa_key'" unless cfg[:private_rsa_key] = config['private_rsa_key']
|
@@ -225,7 +254,7 @@ module SymmetricEncryption
|
|
225
254
|
raise "Missing mandatory 'key_filename' for environment:#{environment} in #{filename}" unless key_filename
|
226
255
|
iv_filename = cipher_cfg['iv_filename'] || cipher_cfg['symmetric_iv_filename']
|
227
256
|
{
|
228
|
-
:
|
257
|
+
:cipher_name => cipher_cfg['cipher_name'] || cipher_cfg['cipher'] || default_cipher,
|
229
258
|
:key_filename => key_filename,
|
230
259
|
:iv_filename => iv_filename,
|
231
260
|
:encoding => cipher_cfg['encoding'],
|
@@ -237,7 +266,7 @@ module SymmetricEncryption
|
|
237
266
|
# Migrate old format config
|
238
267
|
raise "Missing mandatory config parameter 'private_rsa_key'" unless cfg[:private_rsa_key] = config['private_rsa_key']
|
239
268
|
cfg[:ciphers] = [ {
|
240
|
-
:
|
269
|
+
:cipher_name => default_cipher,
|
241
270
|
:key_filename => config['symmetric_key_filename'],
|
242
271
|
:iv_filename => config['symmetric_iv_filename'],
|
243
272
|
} ]
|
@@ -252,16 +281,17 @@ module SymmetricEncryption
|
|
252
281
|
# Raises an Exception on failure
|
253
282
|
#
|
254
283
|
# Parameters:
|
255
|
-
#
|
256
|
-
# Encryption cipher for the symmetric encryption key
|
257
|
-
# private_key
|
284
|
+
# private_rsa_key
|
258
285
|
# Key used to unlock file containing the actual symmetric key
|
259
|
-
#
|
260
|
-
#
|
261
|
-
#
|
262
|
-
#
|
263
|
-
#
|
264
|
-
#
|
286
|
+
# cipher_conf Hash:
|
287
|
+
# cipher_name
|
288
|
+
# Encryption cipher name for the symmetric encryption key
|
289
|
+
# key_filename
|
290
|
+
# Name of file containing symmetric key encrypted using the public
|
291
|
+
# key matching the supplied private_key
|
292
|
+
# iv_filename
|
293
|
+
# Optional. Name of file containing symmetric key initialization vector
|
294
|
+
# encrypted using the public key matching the supplied private_key
|
265
295
|
def self.cipher_from_encrypted_files(private_rsa_key, cipher_conf)
|
266
296
|
# Load Encrypted Symmetric keys
|
267
297
|
key_filename = cipher_conf[:key_filename]
|
@@ -286,11 +316,11 @@ module SymmetricEncryption
|
|
286
316
|
rsa = OpenSSL::PKey::RSA.new(private_rsa_key)
|
287
317
|
iv = rsa.private_decrypt(encrypted_iv) if iv_filename
|
288
318
|
Cipher.new(
|
289
|
-
:key
|
290
|
-
:iv
|
291
|
-
:
|
292
|
-
:encoding
|
293
|
-
:version
|
319
|
+
:key => rsa.private_decrypt(encrypted_key),
|
320
|
+
:iv => iv,
|
321
|
+
:cipher_name => cipher_conf[:cipher_name],
|
322
|
+
:encoding => cipher_conf[:encoding],
|
323
|
+
:version => cipher_conf[:version]
|
294
324
|
)
|
295
325
|
end
|
296
326
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
|
1
3
|
module SymmetricEncryption
|
2
4
|
# Write to encrypted files and other IO streams
|
3
5
|
#
|
@@ -24,12 +26,23 @@ module SymmetricEncryption
|
|
24
26
|
# Default: false
|
25
27
|
#
|
26
28
|
# :random_key [true|false]
|
27
|
-
# Generates a new random key
|
29
|
+
# Generates a new random key for every new file or stream
|
28
30
|
# If true, it forces header to true. Version below then has no effect
|
29
|
-
# The Random key
|
31
|
+
# The Random key will be written to the file/stream in encrypted
|
30
32
|
# form as part of the header
|
31
|
-
# The key
|
33
|
+
# The key is encrypted using the global key
|
32
34
|
# Default: true
|
35
|
+
# Recommended: true.
|
36
|
+
# Setting to false will eventually expose the
|
37
|
+
# encryption key since too much data will be encrypted using the
|
38
|
+
# same encryption key
|
39
|
+
#
|
40
|
+
# :random_iv [true|false]
|
41
|
+
# Generates a new random iv for every new file or stream
|
42
|
+
# If true, it forces header to true.
|
43
|
+
# The Random iv will be written to the file/stream in encrypted
|
44
|
+
# form as part of the header
|
45
|
+
# Default: Value supplied above for :random_key
|
33
46
|
# Recommended: true. Setting to false will eventually expose the
|
34
47
|
# encryption key since too much data will be encrypted using the
|
35
48
|
# same encryption key
|
@@ -49,12 +62,17 @@ module SymmetricEncryption
|
|
49
62
|
#
|
50
63
|
# When random_key is false, the version of the encryption key to use
|
51
64
|
# to encrypt the entire file
|
52
|
-
# Default:
|
65
|
+
# Default: SymmetricEncryption.cipher
|
53
66
|
#
|
54
67
|
# :mode
|
55
68
|
# See File.open for open modes
|
56
69
|
# Default: 'w'
|
57
70
|
#
|
71
|
+
# :cipher_name
|
72
|
+
# The name of the cipher to use only if both :random_key and
|
73
|
+
# :random_iv are true.
|
74
|
+
# Default: SymmetricEncryption.cipher.cipher_name
|
75
|
+
#
|
58
76
|
# Note: Compression occurs before encryption
|
59
77
|
#
|
60
78
|
#
|
@@ -97,22 +115,50 @@ module SymmetricEncryption
|
|
97
115
|
|
98
116
|
# Encrypt data before writing to the supplied stream
|
99
117
|
def initialize(ios,options={})
|
100
|
-
@ios
|
101
|
-
header
|
118
|
+
@ios = ios
|
119
|
+
header = options.fetch(:header, true)
|
120
|
+
random_key = options.fetch(:random_key, true)
|
121
|
+
random_iv = options.fetch(:random_iv, random_key)
|
122
|
+
raise "When :random_key is true, :random_iv must also be true" if random_key && !random_iv
|
102
123
|
# Compress is only used at this point for setting the flag in the header
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
124
|
+
compress = options.fetch(:compress, false)
|
125
|
+
version = options[:version]
|
126
|
+
cipher_name = options[:cipher_name]
|
127
|
+
raise "Cannot supply a :cipher_name unless both :random_key and :random_iv are true" if cipher_name && !random_key && !random_iv
|
128
|
+
|
129
|
+
# Force header if compressed or using random iv, key
|
130
|
+
header = true if compress || random_key || random_iv
|
131
|
+
|
132
|
+
cipher = nil
|
133
|
+
if random_key
|
134
|
+
# Version of key used to encrypt the random key
|
135
|
+
version = SymmetricEncryption.cipher.version
|
136
|
+
else
|
137
|
+
# Use global key if a new random one is not being generated
|
138
|
+
cipher = SymmetricEncryption.cipher(version)
|
139
|
+
raise "Cipher with version:#{version} not found in any of the configured SymmetricEncryption ciphers" unless cipher
|
140
|
+
# Version of key used to encrypt the data
|
141
|
+
version = cipher.version
|
142
|
+
end
|
143
|
+
|
144
|
+
@stream_cipher = ::OpenSSL::Cipher.new(cipher_name || SymmetricEncryption.cipher.cipher_name)
|
145
|
+
@stream_cipher.encrypt
|
107
146
|
|
108
|
-
|
109
|
-
|
110
|
-
raise "Cipher with version:#{options[:version]} not found in any of the configured SymmetricEncryption ciphers" unless @cipher
|
147
|
+
key = random_key ? @stream_cipher.random_key : cipher.send(:key)
|
148
|
+
iv = random_iv ? @stream_cipher.random_iv : cipher.send(:iv)
|
111
149
|
|
112
|
-
@stream_cipher =
|
150
|
+
@stream_cipher.key = key
|
151
|
+
@stream_cipher.iv = iv if iv
|
113
152
|
|
114
153
|
# Write the Encryption header including the random iv, key, and cipher
|
115
|
-
|
154
|
+
if header
|
155
|
+
@ios.write(Cipher.magic_header(
|
156
|
+
version,
|
157
|
+
compress,
|
158
|
+
random_iv ? iv : nil,
|
159
|
+
random_key ? key : nil,
|
160
|
+
cipher_name))
|
161
|
+
end
|
116
162
|
end
|
117
163
|
|
118
164
|
# Close the IO Stream
|