symmetric-encryption 1.1.1 → 2.0.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.
- 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
|