symmetric-encryption 4.2.1 → 4.3.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/lib/symmetric_encryption.rb +6 -2
- data/lib/symmetric_encryption/{railties → active_record}/attr_encrypted.rb +16 -5
- data/lib/symmetric_encryption/active_record/encrypted_attribute.rb +37 -0
- data/lib/symmetric_encryption/cipher.rb +3 -3
- data/lib/symmetric_encryption/core.rb +4 -0
- data/lib/symmetric_encryption/railtie.rb +7 -7
- data/lib/symmetric_encryption/symmetric_encryption.rb +33 -19
- data/lib/symmetric_encryption/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5499f0c6e33fc5eee0a2295623edd3bf35a247e1a6263a3e93f2c4e57219f22
|
4
|
+
data.tar.gz: ea3495cf8f5fe6b388725cd424ed13dc8b982c4ad225e78c7056f8d0f0d70cab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8a920045c6b813bb55e8a518727ffdaf03b0b5857f5326d8b6003946d81fb162f28eea69617934622626de66cbfbeaf27b464c5d7baa21e07332e2c7098f7e4
|
7
|
+
data.tar.gz: bb2a832909e3a81b1e357a4ec650e7f1fd93e81ab08a0a0f3664b586bc0bf60f1a821c26831f456138e77a7a29575bc976890f608ac10461a51e5fd86dbd2699
|
data/lib/symmetric_encryption.rb
CHANGED
@@ -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/
|
13
|
+
require 'symmetric_encryption/active_record/attr_encrypted'
|
14
14
|
require 'symmetric_encryption/railties/symmetric_encryption_validator'
|
15
15
|
|
16
|
-
ActiveRecord::
|
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
|
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(*
|
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
|
-
|
51
|
+
random_iv = true if random_iv.nil? && SymmetricEncryption.randomize_iv?
|
52
52
|
|
53
|
-
|
54
|
-
|
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 [
|
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:
|
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:
|
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
|
33
|
-
|
34
|
-
|
35
|
-
|
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
|
-
|
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
|
52
|
+
return @cipher if version.nil? || (@cipher.version == version)
|
58
53
|
|
59
|
-
secondary_ciphers.find { |c| c.version == version } || (
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
142
|
+
elsif @select_cipher
|
137
143
|
# Use cipher_selector if present to decide which cipher to use
|
138
|
-
|
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
|
-
#
|
176
|
-
#
|
177
|
-
#
|
178
|
-
#
|
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:
|
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
|
-
|
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
|
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.
|
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-
|
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.
|
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
|