attr_keyring 0.7.0 → 0.8.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/.github/workflows/tests.yml +4 -4
- data/.rubocop.yml +2 -8
- data/README.md +3 -2
- data/attr_keyring.gemspec +1 -1
- data/gemfiles/7_0.gemfile +1 -1
- data/gemfiles/{6_0.gemfile → 7_1.gemfile} +1 -1
- data/lib/attr_keyring/active_record.rb +1 -1
- data/lib/attr_keyring/version.rb +1 -1
- data/lib/attr_keyring.rb +13 -13
- data/lib/keyring/encryptor/aes.rb +32 -5
- metadata +5 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 48738717eed1a26ac48bc94857c835d729794b22a5d79a55aaa41a0d6fe9d788
|
|
4
|
+
data.tar.gz: 37f7c705a1cb47d21a3bcab81c0f0d644eb572553c06e117b41e599fdaf14d10
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f03879a674680dde8cfddee663e7fee8a0b72132d79022a655635b9a8808a5e29c77515a8e3aeef4f4fe23343e5507191434b0520f357b49c4592155571843b0
|
|
7
|
+
data.tar.gz: 6bcb69b86dfd9a23389a703f370d62de3c71159faf85534916a97747cda3619cbc1c196cd17878636fc46f9fcdcf0c9872a64d773f4490dec730aa79c6a1e5c3
|
data/.github/workflows/tests.yml
CHANGED
|
@@ -14,11 +14,11 @@ jobs:
|
|
|
14
14
|
strategy:
|
|
15
15
|
fail-fast: false
|
|
16
16
|
matrix:
|
|
17
|
-
ruby: ["
|
|
17
|
+
ruby: ["3.0", "3.1", "3.2"]
|
|
18
18
|
gemfile:
|
|
19
|
+
- gemfiles/7_1.gemfile
|
|
19
20
|
- gemfiles/7_0.gemfile
|
|
20
21
|
- gemfiles/6_1.gemfile
|
|
21
|
-
- gemfiles/6_0.gemfile
|
|
22
22
|
|
|
23
23
|
services:
|
|
24
24
|
postgres:
|
|
@@ -29,9 +29,9 @@ jobs:
|
|
|
29
29
|
--health-retries 5
|
|
30
30
|
|
|
31
31
|
steps:
|
|
32
|
-
- uses: actions/checkout@
|
|
32
|
+
- uses: actions/checkout@v4.1.7
|
|
33
33
|
|
|
34
|
-
- uses: actions/cache@
|
|
34
|
+
- uses: actions/cache@v4.0.2
|
|
35
35
|
with:
|
|
36
36
|
path: vendor/bundle
|
|
37
37
|
key: >
|
data/.rubocop.yml
CHANGED
|
@@ -3,20 +3,14 @@ inherit_gem:
|
|
|
3
3
|
rubocop-fnando: .rubocop.yml
|
|
4
4
|
|
|
5
5
|
AllCops:
|
|
6
|
-
TargetRubyVersion:
|
|
6
|
+
TargetRubyVersion: 3.3
|
|
7
7
|
Exclude:
|
|
8
8
|
- vendor/**/*
|
|
9
9
|
- gemfiles/**/*
|
|
10
10
|
|
|
11
|
-
Metrics/AbcSize:
|
|
12
|
-
Enabled: false
|
|
13
|
-
|
|
14
11
|
Layout/LineLength:
|
|
15
12
|
Exclude:
|
|
16
13
|
- test/**/*
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
Enabled: false
|
|
20
|
-
|
|
21
|
-
Metrics/ClassLength:
|
|
15
|
+
Minitest/NoAssertions:
|
|
22
16
|
Enabled: false
|
data/README.md
CHANGED
|
@@ -60,8 +60,8 @@ puts "✉️ #{decrypted}"
|
|
|
60
60
|
|
|
61
61
|
#### Change encryption algorithm
|
|
62
62
|
|
|
63
|
-
You can choose between `AES-128-CBC`, `AES-192-CBC
|
|
64
|
-
default, `AES-128-CBC` will be used.
|
|
63
|
+
You can choose between `AES-128-CBC`, `AES-192-CBC`, `AES-256-CBC`, and
|
|
64
|
+
`AES-256-GCM`. By default, `AES-128-CBC` will be used.
|
|
65
65
|
|
|
66
66
|
To specify the encryption algorithm, set the `encryption` option. The following
|
|
67
67
|
example uses `AES-256-CBC`.
|
|
@@ -186,6 +186,7 @@ the size as half of it is used for HMAC computation.
|
|
|
186
186
|
- `aes-128-cbc`: 16 bytes (encryption) + 16 bytes (HMAC).
|
|
187
187
|
- `aes-192-cbc`: 24 bytes (encryption) + 24 bytes (HMAC).
|
|
188
188
|
- `aes-256-cbc`: 32 bytes (encryption) + 32 bytes (HMAC).
|
|
189
|
+
- `aes-256-gcm`: 32 bytes (encryption) + 32 bytes (HMAC).
|
|
189
190
|
|
|
190
191
|
#### About the encrypted message
|
|
191
192
|
|
data/attr_keyring.gemspec
CHANGED
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
|
12
12
|
spec.description = spec.summary
|
|
13
13
|
spec.homepage = "https://github.com/fnando/attr_keyring"
|
|
14
14
|
spec.license = "MIT"
|
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new(">=
|
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.3.0")
|
|
16
16
|
|
|
17
17
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
18
18
|
`git ls-files -z`
|
data/gemfiles/7_0.gemfile
CHANGED
data/lib/attr_keyring/version.rb
CHANGED
data/lib/attr_keyring.rb
CHANGED
|
@@ -55,7 +55,7 @@ module AttrKeyring
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def define_attr_encrypt_writer(attribute)
|
|
58
|
-
define_method("#{attribute}=") do |value|
|
|
58
|
+
define_method(:"#{attribute}=") do |value|
|
|
59
59
|
attr_encrypt_column(attribute, value)
|
|
60
60
|
end
|
|
61
61
|
end
|
|
@@ -80,12 +80,12 @@ module AttrKeyring
|
|
|
80
80
|
encrypted_value, keyring_id, digest =
|
|
81
81
|
self.class.keyring.encrypt(value, previous_keyring_id)
|
|
82
82
|
|
|
83
|
-
public_send("#{self.class.keyring_column_name}=", keyring_id)
|
|
84
|
-
public_send("encrypted_#{attribute}=", encrypted_value)
|
|
83
|
+
public_send(:"#{self.class.keyring_column_name}=", keyring_id)
|
|
84
|
+
public_send(:"encrypted_#{attribute}=", encrypted_value)
|
|
85
85
|
|
|
86
|
-
return unless respond_to?("#{attribute}_digest=")
|
|
86
|
+
return unless respond_to?(:"#{attribute}_digest=")
|
|
87
87
|
|
|
88
|
-
public_send("#{attribute}_digest=", digest)
|
|
88
|
+
public_send(:"#{attribute}_digest=", digest)
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
private def attr_decrypt_column(attribute)
|
|
@@ -95,7 +95,7 @@ module AttrKeyring
|
|
|
95
95
|
return instance_variable_get(cache_name)
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
-
encrypted_value = public_send("encrypted_#{attribute}")
|
|
98
|
+
encrypted_value = public_send(:"encrypted_#{attribute}")
|
|
99
99
|
|
|
100
100
|
return unless encrypted_value
|
|
101
101
|
|
|
@@ -119,9 +119,9 @@ module AttrKeyring
|
|
|
119
119
|
end
|
|
120
120
|
|
|
121
121
|
private def reset_encrypted_column(attribute)
|
|
122
|
-
public_send("encrypted_#{attribute}=", nil)
|
|
123
|
-
if respond_to?("#{attribute}_digest=")
|
|
124
|
-
public_send("#{attribute}_digest=", nil)
|
|
122
|
+
public_send(:"encrypted_#{attribute}=", nil)
|
|
123
|
+
if respond_to?(:"#{attribute}_digest=")
|
|
124
|
+
public_send(:"#{attribute}_digest=", nil)
|
|
125
125
|
end
|
|
126
126
|
nil
|
|
127
127
|
end
|
|
@@ -140,14 +140,14 @@ module AttrKeyring
|
|
|
140
140
|
|
|
141
141
|
encrypted_value, _, digest = self.class.keyring.encrypt(value)
|
|
142
142
|
|
|
143
|
-
public_send("encrypted_#{attribute}=", encrypted_value)
|
|
143
|
+
public_send(:"encrypted_#{attribute}=", encrypted_value)
|
|
144
144
|
|
|
145
|
-
if respond_to?("#{attribute}_digest")
|
|
146
|
-
public_send("#{attribute}_digest=", digest)
|
|
145
|
+
if respond_to?(:"#{attribute}_digest")
|
|
146
|
+
public_send(:"#{attribute}_digest=", digest)
|
|
147
147
|
end
|
|
148
148
|
end
|
|
149
149
|
|
|
150
|
-
public_send("#{self.class.keyring_column_name}=", keyring_id)
|
|
150
|
+
public_send(:"#{self.class.keyring_column_name}=", keyring_id)
|
|
151
151
|
end
|
|
152
152
|
|
|
153
153
|
private def encryptable_value?(value)
|
|
@@ -12,29 +12,35 @@ module Keyring
|
|
|
12
12
|
@key_size ||= build_cipher.key_len
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
+
def self.support_auth_data?
|
|
16
|
+
false
|
|
17
|
+
end
|
|
18
|
+
|
|
15
19
|
def self.encrypt(key, message)
|
|
16
20
|
cipher = build_cipher
|
|
17
21
|
cipher.encrypt
|
|
18
22
|
iv = cipher.random_iv
|
|
19
23
|
cipher.iv = iv
|
|
20
24
|
cipher.key = key.encryption_key
|
|
25
|
+
cipher.auth_data = "" if support_auth_data?
|
|
21
26
|
encrypted = cipher.update(message) + cipher.final
|
|
22
|
-
|
|
27
|
+
auth_tag = ""
|
|
28
|
+
auth_tag = cipher.auth_tag if support_auth_data?
|
|
29
|
+
hmac = hmac_digest(key.signing_key, "#{auth_tag}#{iv}#{encrypted}")
|
|
23
30
|
|
|
24
|
-
Base64.strict_encode64("#{hmac}#{iv}#{encrypted}")
|
|
31
|
+
Base64.strict_encode64("#{hmac}#{auth_tag}#{iv}#{encrypted}")
|
|
25
32
|
end
|
|
26
33
|
|
|
27
34
|
def self.decrypt(key, message)
|
|
28
35
|
cipher = build_cipher
|
|
36
|
+
iv_size = cipher.random_iv.size
|
|
29
37
|
cipher.decrypt
|
|
30
38
|
|
|
31
39
|
message = Base64.strict_decode64(message)
|
|
32
40
|
|
|
33
41
|
hmac = message[0...32]
|
|
34
|
-
encrypted_payload = message[32..-1]
|
|
35
|
-
iv = encrypted_payload[0...16]
|
|
36
|
-
encrypted = encrypted_payload[16..-1]
|
|
37
42
|
|
|
43
|
+
encrypted_payload = message[32..-1]
|
|
38
44
|
expected_hmac = hmac_digest(key.signing_key, encrypted_payload)
|
|
39
45
|
|
|
40
46
|
unless verify_signature(expected_hmac, hmac)
|
|
@@ -44,8 +50,19 @@ module Keyring
|
|
|
44
50
|
"got #{Base64.strict_encode64(hmac)} instead"
|
|
45
51
|
end
|
|
46
52
|
|
|
53
|
+
auth_tag = ""
|
|
54
|
+
auth_tag = encrypted_payload[0...16] if support_auth_data?
|
|
55
|
+
iv = encrypted_payload[auth_tag.size...(auth_tag.size + iv_size)]
|
|
56
|
+
encrypted = encrypted_payload[(auth_tag.size + iv_size)..-1]
|
|
57
|
+
|
|
47
58
|
cipher.iv = iv
|
|
48
59
|
cipher.key = key.encryption_key
|
|
60
|
+
|
|
61
|
+
if support_auth_data?
|
|
62
|
+
cipher.auth_data = ""
|
|
63
|
+
cipher.auth_tag = auth_tag
|
|
64
|
+
end
|
|
65
|
+
|
|
49
66
|
cipher.update(encrypted) + cipher.final
|
|
50
67
|
end
|
|
51
68
|
|
|
@@ -80,6 +97,16 @@ module Keyring
|
|
|
80
97
|
"AES-256-CBC"
|
|
81
98
|
end
|
|
82
99
|
end
|
|
100
|
+
|
|
101
|
+
class AES256GCM < Base
|
|
102
|
+
def self.cipher_name
|
|
103
|
+
"AES-256-GCM"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def self.support_auth_data?
|
|
107
|
+
true
|
|
108
|
+
end
|
|
109
|
+
end
|
|
83
110
|
end
|
|
84
111
|
end
|
|
85
112
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: attr_keyring
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nando Vieira
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activerecord
|
|
@@ -203,9 +202,9 @@ files:
|
|
|
203
202
|
- examples/active_record_sample.rb
|
|
204
203
|
- examples/keyring_sample.rb
|
|
205
204
|
- examples/sequel_sample.rb
|
|
206
|
-
- gemfiles/6_0.gemfile
|
|
207
205
|
- gemfiles/6_1.gemfile
|
|
208
206
|
- gemfiles/7_0.gemfile
|
|
207
|
+
- gemfiles/7_1.gemfile
|
|
209
208
|
- lib/attr_keyring.rb
|
|
210
209
|
- lib/attr_keyring/active_record.rb
|
|
211
210
|
- lib/attr_keyring/encoders/json_encoder.rb
|
|
@@ -218,7 +217,6 @@ homepage: https://github.com/fnando/attr_keyring
|
|
|
218
217
|
licenses:
|
|
219
218
|
- MIT
|
|
220
219
|
metadata: {}
|
|
221
|
-
post_install_message:
|
|
222
220
|
rdoc_options: []
|
|
223
221
|
require_paths:
|
|
224
222
|
- lib
|
|
@@ -226,15 +224,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
226
224
|
requirements:
|
|
227
225
|
- - ">="
|
|
228
226
|
- !ruby/object:Gem::Version
|
|
229
|
-
version:
|
|
227
|
+
version: 3.3.0
|
|
230
228
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
231
229
|
requirements:
|
|
232
230
|
- - ">="
|
|
233
231
|
- !ruby/object:Gem::Version
|
|
234
232
|
version: '0'
|
|
235
233
|
requirements: []
|
|
236
|
-
rubygems_version:
|
|
237
|
-
signing_key:
|
|
234
|
+
rubygems_version: 4.0.3
|
|
238
235
|
specification_version: 4
|
|
239
236
|
summary: Simple encryption-at-rest plugin for ActiveRecord.
|
|
240
237
|
test_files: []
|