symmetric-encryption 4.2.1 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40e60b20cfaf40c1b3ad68fb05b12fd766886ac3d4527a02c8d456906e45b705
4
- data.tar.gz: 3c87cffcfc26fe8a057619b3559c3f93ff5a3951c219eb90deb1c2054ae4495f
3
+ metadata.gz: d5499f0c6e33fc5eee0a2295623edd3bf35a247e1a6263a3e93f2c4e57219f22
4
+ data.tar.gz: ea3495cf8f5fe6b388725cd424ed13dc8b982c4ad225e78c7056f8d0f0d70cab
5
5
  SHA512:
6
- metadata.gz: 479105df621736ea8ccaddc73129f4c6d9ebad8a6918a793044d9d3329f547e3a7cbd404719bcbd9918a5cedb0c18694f22173201e799ab70d3a8032a7a90ac6
7
- data.tar.gz: dd8fd1b290bc1e2e55311234e8a06660dbc6f0849382189bc9408432caa519f973a1cbb7835eb97805136699eaf357772531cb7dfe6dbe2a62c33b4600c141f5
6
+ metadata.gz: a8a920045c6b813bb55e8a518727ffdaf03b0b5857f5326d8b6003946d81fb162f28eea69617934622626de66cbfbeaf27b464c5d7baa21e07332e2c7098f7e4
7
+ data.tar.gz: bb2a832909e3a81b1e357a4ec650e7f1fd93e81ab08a0a0f3664b586bc0bf60f1a821c26831f456138e77a7a29575bc976890f608ac10461a51e5fd86dbd2699
@@ -10,10 +10,14 @@ end
10
10
  begin
11
11
  require 'active_support'
12
12
  ActiveSupport.on_load(:active_record) do
13
- require 'symmetric_encryption/railties/attr_encrypted'
13
+ require 'symmetric_encryption/active_record/attr_encrypted'
14
14
  require 'symmetric_encryption/railties/symmetric_encryption_validator'
15
15
 
16
- ActiveRecord::Base.include(SymmetricEncryption::Railties::AttrEncrypted)
16
+ if ActiveRecord.version >= Gem::Version.new('5.0.0')
17
+ ActiveRecord::Type.register(:encrypted, SymmetricEncryption::ActiveRecord::EncryptedAttribute)
18
+ end
19
+
20
+ ActiveRecord::Base.include(SymmetricEncryption::ActiveRecord::AttrEncrypted)
17
21
  end
18
22
 
19
23
  ActiveSupport.on_load(:mongoid) do
@@ -1,5 +1,5 @@
1
1
  module SymmetricEncryption
2
- module Railties
2
+ module ActiveRecord
3
3
  module AttrEncrypted
4
4
  def self.included(base)
5
5
  base.extend ClassMethods
@@ -39,7 +39,7 @@ module SymmetricEncryption
39
39
  # compression
40
40
  # Note: Adds a 6 byte header prior to encoding, only if :random_iv is false
41
41
  # Default: false
42
- def attr_encrypted(*params)
42
+ def attr_encrypted(*attributes, random_iv: nil, type: :string, compress: false)
43
43
  # Ensure ActiveRecord has created all its methods first
44
44
  # Ignore failures since the table may not yet actually exist
45
45
  begin
@@ -48,10 +48,21 @@ module SymmetricEncryption
48
48
  nil
49
49
  end
50
50
 
51
- options = params.last.is_a?(Hash) ? params.pop.dup : {}
51
+ random_iv = true if random_iv.nil? && SymmetricEncryption.randomize_iv?
52
52
 
53
- params.each do |attribute|
54
- SymmetricEncryption::Generator.generate_decrypted_accessors(self, attribute, "encrypted_#{attribute}", options)
53
+ if random_iv.nil?
54
+ warn("attr_encrypted() no longer allows a default value for option `random_iv`. Add `random_iv: false` if it is required.")
55
+ end
56
+
57
+ attributes.each do |attribute|
58
+ SymmetricEncryption::Generator.generate_decrypted_accessors(
59
+ self,
60
+ attribute,
61
+ "encrypted_#{attribute}",
62
+ random_iv: random_iv,
63
+ type: type,
64
+ compress: compress
65
+ )
55
66
  encrypted_attributes[attribute.to_sym] = "encrypted_#{attribute}".to_sym
56
67
  end
57
68
  end
@@ -0,0 +1,37 @@
1
+ module SymmetricEncryption
2
+ module ActiveRecord
3
+ class EncryptedAttribute < ::ActiveModel::Type::String
4
+ def initialize(random_iv: true, compress: false, type: :string)
5
+ @random_iv = random_iv
6
+ @compress = compress
7
+ @encrypted_type = type
8
+ end
9
+
10
+ def deserialize(value)
11
+ return if value.nil?
12
+
13
+ SymmetricEncryption.decrypt(value, type: encrypted_type)
14
+ end
15
+
16
+ def serialize(value)
17
+ return if value.nil?
18
+
19
+ SymmetricEncryption.encrypt(
20
+ value,
21
+ type: encrypted_type,
22
+ compress: compress,
23
+ random_iv: random_iv
24
+ )
25
+ end
26
+
27
+ private
28
+
29
+ # Symmetric Encryption uses coercible gem to handle casting
30
+ def cast_value(value)
31
+ value
32
+ end
33
+
34
+ attr_reader :random_iv, :compress, :encrypted_type
35
+ end
36
+ end
37
+ end
@@ -58,7 +58,7 @@ module SymmetricEncryption
58
58
  # Return as raw binary data string. Note: String can contain embedded nulls
59
59
  # Default: :base64strict
60
60
  #
61
- # version [Fixnum]
61
+ # version [Integer]
62
62
  # Optional. The version number of this encryption key
63
63
  # Used by SymmetricEncryption to select the correct key when decrypting data
64
64
  # Valid Range: 0..255
@@ -131,7 +131,7 @@ module SymmetricEncryption
131
131
  # * Should only be used for large strings since compression overhead and
132
132
  # the overhead of adding the encryption header may exceed any benefits of
133
133
  # compression
134
- def encrypt(str, random_iv: false, compress: false, header: always_add_header)
134
+ def encrypt(str, random_iv: SymmetricEncryption.randomize_iv?, compress: false, header: always_add_header)
135
135
  return if str.nil?
136
136
 
137
137
  str = str.to_s
@@ -246,7 +246,7 @@ module SymmetricEncryption
246
246
  # Default: `always_add_header`
247
247
  #
248
248
  # See #encrypt to encrypt and encode the result as a string.
249
- def binary_encrypt(str, random_iv: false, compress: false, header: always_add_header)
249
+ def binary_encrypt(str, random_iv: SymmetricEncryption.randomize_iv?, compress: false, header: always_add_header)
250
250
  return if str.nil?
251
251
 
252
252
  string = str.to_s
@@ -13,6 +13,7 @@ module SymmetricEncryption
13
13
  autoload :Coerce, 'symmetric_encryption/coerce'
14
14
  autoload :Config, 'symmetric_encryption/config'
15
15
  autoload :Encoder, 'symmetric_encryption/encoder'
16
+ autoload :EncryptedStringType, 'symmetric_encryption/types/encrypted_string_type'
16
17
  autoload :Generator, 'symmetric_encryption/generator'
17
18
  autoload :Header, 'symmetric_encryption/header'
18
19
  autoload :Key, 'symmetric_encryption/key'
@@ -21,6 +22,9 @@ module SymmetricEncryption
21
22
  autoload :Writer, 'symmetric_encryption/writer'
22
23
  autoload :CLI, 'symmetric_encryption/cli'
23
24
  autoload :Keystore, 'symmetric_encryption/keystore'
25
+ module ActiveRecord
26
+ autoload :EncryptedAttribute, 'symmetric_encryption/active_record/encrypted_attribute'
27
+ end
24
28
  module Utils
25
29
  autoload :Aws, 'symmetric_encryption/utils/aws'
26
30
  autoload :Files, 'symmetric_encryption/utils/files'
@@ -29,13 +29,15 @@ module SymmetricEncryption #:nodoc:
29
29
  config.before_configuration do
30
30
  # Check if already configured
31
31
  unless ::SymmetricEncryption.cipher?
32
- app_name = Rails::Application.subclasses.first.parent.to_s.underscore
33
- config_file =
34
- if (env_var = ENV['SYMMETRIC_ENCRYPTION_CONFIG'])
35
- Pathname.new File.expand_path(env_var)
32
+ app_name = Rails::Application.subclasses.first.parent.to_s.underscore
33
+ env_var = ENV['SYMMETRIC_ENCRYPTION_CONFIG']
34
+ config_file =
35
+ if env_var
36
+ Pathname.new(File.expand_path(env_var))
36
37
  else
37
38
  Rails.root.join('config', 'symmetric-encryption.yml')
38
39
  end
40
+
39
41
  if config_file.file?
40
42
  begin
41
43
  ::SymmetricEncryption::Config.load!(file_name: config_file, env: ENV['SYMMETRIC_ENCRYPTION_ENV'] || Rails.env)
@@ -45,10 +47,8 @@ module SymmetricEncryption #:nodoc:
45
47
  puts "To generate a new config file and key files: symmetric-encryption --generate --app-name #{app_name}\n\n"
46
48
  raise(exc)
47
49
  end
48
- else
49
- puts "\nSymmetric Encryption config not found."
50
- puts "To generate a new config file and key files: symmetric-encryption --generate --app-name #{app_name}\n\n"
51
50
  end
51
+
52
52
  end
53
53
  end
54
54
  end
@@ -8,11 +8,6 @@ require 'erb'
8
8
  # The symmetric key is protected using the private key below and must
9
9
  # be distributed separately from the application
10
10
  module SymmetricEncryption
11
- # Defaults
12
- @@cipher = nil
13
- @@secondary_ciphers = []
14
- @@select_cipher = nil
15
-
16
11
  # List of types supported when encrypting or decrypting data
17
12
  #
18
13
  # Each type maps to the built-in Ruby types as follows:
@@ -39,7 +34,7 @@ module SymmetricEncryption
39
34
  def self.cipher=(cipher)
40
35
  raise(ArgumentError, 'Cipher must respond to :encrypt and :decrypt') unless cipher.nil? || (cipher.respond_to?(:encrypt) && cipher.respond_to?(:decrypt))
41
36
 
42
- @@cipher = cipher
37
+ @cipher = cipher
43
38
  end
44
39
 
45
40
  # Returns the Primary Symmetric Cipher being used
@@ -54,14 +49,14 @@ module SymmetricEncryption
54
49
  )
55
50
  end
56
51
 
57
- return @@cipher if version.nil? || (@@cipher.version == version)
52
+ return @cipher if version.nil? || (@cipher.version == version)
58
53
 
59
- secondary_ciphers.find { |c| c.version == version } || (@@cipher if version.zero?)
54
+ secondary_ciphers.find { |c| c.version == version } || (@cipher if version.zero?)
60
55
  end
61
56
 
62
57
  # Returns whether a primary cipher has been set
63
58
  def self.cipher?
64
- !@@cipher.nil?
59
+ !@cipher.nil?
65
60
  end
66
61
 
67
62
  # Set the Secondary Symmetric Ciphers Array to be used
@@ -71,12 +66,23 @@ module SymmetricEncryption
71
66
  secondary_ciphers.each do |cipher|
72
67
  raise(ArgumentError, 'secondary_ciphers can only consist of SymmetricEncryption::Ciphers') unless cipher.respond_to?(:encrypt) && cipher.respond_to?(:decrypt)
73
68
  end
74
- @@secondary_ciphers = secondary_ciphers
69
+ @secondary_ciphers = secondary_ciphers
75
70
  end
76
71
 
77
72
  # Returns the Primary Symmetric Cipher being used
78
73
  def self.secondary_ciphers
79
- @@secondary_ciphers
74
+ @secondary_ciphers
75
+ end
76
+
77
+ # Whether to randomize the iv by default.
78
+ # true: Generate a new random IV by default. [HIGHLY RECOMMENDED]
79
+ # false: Do not generate a new random IV by default.
80
+ def self.randomize_iv?
81
+ @randomize_iv
82
+ end
83
+
84
+ def self.randomize_iv=(randomize_iv)
85
+ @randomize_iv = randomize_iv
80
86
  end
81
87
 
82
88
  # Decrypt supplied string.
@@ -133,9 +139,9 @@ module SymmetricEncryption
133
139
  if version
134
140
  # Supplied version takes preference
135
141
  cipher(version)
136
- elsif @@select_cipher
142
+ elsif @select_cipher
137
143
  # Use cipher_selector if present to decide which cipher to use
138
- @@select_cipher.call(str, decoded)
144
+ @select_cipher.call(str, decoded)
139
145
  else
140
146
  # Global cipher
141
147
  cipher
@@ -172,10 +178,12 @@ module SymmetricEncryption
172
178
  # to convert it to a string
173
179
  #
174
180
  # random_iv [true|false]
175
- # Whether the encypted value should use a random IV every time the
176
- # field is encrypted.
177
- # It is recommended to set this to true where feasible. If the encrypted
178
- # value could be used as part of a SQL where clause, or as part
181
+ # Mandatory unless `SymmetricEncryption.randomize_iv = true` has been called.
182
+ #
183
+ # Whether the encrypted value should use a random IV every time the field is encrypted.
184
+ # It is recommended to set this to true where possible.
185
+ #
186
+ # If the encrypted value could be used as part of a SQL where clause, or as part
179
187
  # of any lookup, then it must be false.
180
188
  # Setting random_iv to true will result in a different encrypted output for
181
189
  # the same input string.
@@ -203,7 +211,7 @@ module SymmetricEncryption
203
211
  # Note: If type is set to something other than :string, it's expected that
204
212
  # the coercible gem is available in the path.
205
213
  # Default: :string
206
- def self.encrypt(str, random_iv: false, compress: false, type: :string, header: cipher.always_add_header)
214
+ def self.encrypt(str, random_iv: SymmetricEncryption.randomize_iv?, compress: false, type: :string, header: cipher.always_add_header)
207
215
  return str if str.nil? || (str == '')
208
216
 
209
217
  # Encrypt and then encode the supplied string
@@ -265,7 +273,7 @@ module SymmetricEncryption
265
273
  # encoded_str.end_with?("\n") ? SymmetricEncryption.cipher(0) : SymmetricEncryption.cipher
266
274
  # end
267
275
  def self.select_cipher(&block)
268
- @@select_cipher = block || nil
276
+ @select_cipher = block || nil
269
277
  end
270
278
 
271
279
  # Load the Encryption Configuration from a YAML file
@@ -288,4 +296,10 @@ module SymmetricEncryption
288
296
 
289
297
  BINARY_ENCODING = Encoding.find('binary')
290
298
  UTF8_ENCODING = Encoding.find('UTF-8')
299
+
300
+ # Defaults
301
+ @cipher = nil
302
+ @secondary_ciphers = []
303
+ @select_cipher = nil
304
+ @random_iv = false
291
305
  end
@@ -1,3 +1,3 @@
1
1
  module SymmetricEncryption
2
- VERSION = '4.2.1'.freeze
2
+ VERSION = '4.3.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: symmetric-encryption
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.1
4
+ version: 4.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-04 00:00:00.000000000 Z
11
+ date: 2019-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coercible
@@ -38,6 +38,8 @@ files:
38
38
  - bin/symmetric-encryption
39
39
  - lib/symmetric-encryption.rb
40
40
  - lib/symmetric_encryption.rb
41
+ - lib/symmetric_encryption/active_record/attr_encrypted.rb
42
+ - lib/symmetric_encryption/active_record/encrypted_attribute.rb
41
43
  - lib/symmetric_encryption/cipher.rb
42
44
  - lib/symmetric_encryption/cli.rb
43
45
  - lib/symmetric_encryption/coerce.rb
@@ -56,7 +58,6 @@ files:
56
58
  - lib/symmetric_encryption/keystore/heroku.rb
57
59
  - lib/symmetric_encryption/keystore/memory.rb
58
60
  - lib/symmetric_encryption/railtie.rb
59
- - lib/symmetric_encryption/railties/attr_encrypted.rb
60
61
  - lib/symmetric_encryption/railties/mongoid_encrypted.rb
61
62
  - lib/symmetric_encryption/railties/symmetric_encryption_validator.rb
62
63
  - lib/symmetric_encryption/reader.rb
@@ -86,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
87
  - !ruby/object:Gem::Version
87
88
  version: '0'
88
89
  requirements: []
89
- rubygems_version: 3.0.2
90
+ rubygems_version: 3.0.3
90
91
  signing_key:
91
92
  specification_version: 4
92
93
  summary: Encrypt ActiveRecord and Mongoid attributes, files and passwords in configuration