sidekiq-field-encryptor 0.1.1 → 0.2.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
- SHA1:
3
- metadata.gz: d7b580f10f55bd99cc1b08a0d41157746562b155
4
- data.tar.gz: d93bb7059b52325809a24f161c98ec4b705f9323
2
+ SHA256:
3
+ metadata.gz: c11c669792764e011bd552df7369298eaa77961b1e83c55047c172db8bce861e
4
+ data.tar.gz: 2d3604aa814fc4baa6b2597a16231348de41b5bb36efe3946ee7b3b6cfe2cf47
5
5
  SHA512:
6
- metadata.gz: 73208766812240af540b2fac93f98f4d585ffb0065dda731dbd47be7b01ee4d4b8eab048925c2254c465ce46ecaf0a775ffb6a6e010c1b52d429f04119992f02
7
- data.tar.gz: 04f77a80f08b85d429c804a38b2244a4f5f564cd6a4a5e7704fb9727796261d7280a0fc47f80a4d3f593d9a6940be13f9b397c6d4f930a38eb294440012aa048
6
+ metadata.gz: 6d7468111be23b540a4a3e1ed44771097902bef7a591a3c67ae0ad9a6a609402567f299f575eff127f3862f35d191c7c959d8cd44c618bc33a116031cff5d224
7
+ data.tar.gz: fb7827f9988d5ec43d124fcc9f08481cb4ebda5bfd5ddf80836c03cbef64e7954ef1db6a3efb485c2cd18f1856d5866324fd06d0f2b2010c7ca6a3e121a8f7ce
@@ -1,5 +1,6 @@
1
1
  require 'base64'
2
2
  require 'encryptor'
3
+ require 'json'
3
4
  require 'sidekiq-field-encryptor/version'
4
5
 
5
6
  # This middleware configures encryption of any fields that can contain sensitive
@@ -21,30 +22,69 @@ require 'sidekiq-field-encryptor/version'
21
22
  # Will encrypt the values {'x' => 1} and 'b' when storing the job in Redis and
22
23
  # decrypt the values inside the client before the job is executed.
23
24
  module SidekiqFieldEncryptor
25
+ SERIALIZE_JSON = 'json'.freeze
26
+ SERIALIZE_MARHSALL = 'marshal'.freeze
27
+
24
28
  class Base
25
29
  def initialize(options = {})
26
30
  @encryption_key = options[:encryption_key]
27
31
  @encrypted_fields = options[:encrypted_fields] || {}
28
32
  @encryption_algorithm = options[:encryption_algorithm] || 'aes-256-gcm'
33
+
34
+ @serialization_method = options[:serialization_method] || SERIALIZE_JSON
35
+ @serialization_compat = options[:serialization_compat]
29
36
  end
30
37
 
31
38
  def assert_key_configured
32
39
  raise 'Encryption key not configured' if @encryption_key.nil?
33
40
  end
34
41
 
42
+ def serialize(value)
43
+ case @serialization_method
44
+ when SERIALIZE_JSON
45
+ JSON.generate(value, quirks_mode: true)
46
+ when SERIALIZE_MARHSALL
47
+ Marshal.dump(value)
48
+ else
49
+ raise "Invalid serialization_method: #{@serialization_method}"
50
+ end
51
+ end
52
+
53
+ def deserialize(method, value)
54
+ if !@serialization_compat && method != @serialization_method
55
+ raise "Invalid serialization_method received: #{method}"
56
+ end
57
+
58
+ case method
59
+ when SERIALIZE_JSON
60
+ JSON.parse(value, quirks_mode: true)
61
+ when SERIALIZE_MARHSALL, nil
62
+ # No method used to be Marshall, so we respect this here
63
+ Marshal.load(value)
64
+ else
65
+ raise "Invalid serialization_method: #{@serialization_method}"
66
+ end
67
+ end
68
+
35
69
  def encrypt(value)
36
- plaintext = Marshal.dump(value)
70
+ plaintext = serialize(value)
37
71
  iv = OpenSSL::Cipher::Cipher.new(@encryption_algorithm).random_iv
38
72
  args = { key: @encryption_key, iv: iv, algorithm: @encryption_algorithm }
39
73
  ciphertext = ::Encryptor.encrypt(plaintext, **args)
40
- [::Base64.encode64(ciphertext), ::Base64.encode64(iv)]
74
+ [
75
+ ::Base64.encode64(ciphertext),
76
+ ::Base64.encode64(iv),
77
+ @serialization_method
78
+ ]
41
79
  end
42
80
 
43
81
  def decrypt(encrypted)
44
- ciphertext, iv = encrypted.map { |value| ::Base64.decode64(value) }
82
+ base64_ciphertext, base64_iv, serialization_method = encrypted
83
+ ciphertext = ::Base64.decode64(base64_ciphertext)
84
+ iv = ::Base64.decode64(base64_iv)
45
85
  args = { key: @encryption_key, iv: iv, algorithm: @encryption_algorithm }
46
86
  plaintext = ::Encryptor.decrypt(ciphertext, **args)
47
- Marshal.load(plaintext)
87
+ deserialize(serialization_method, plaintext)
48
88
  end
49
89
 
50
90
  def process_message(message)
@@ -1,3 +1,3 @@
1
1
  module SidekiqFieldEncryptor
2
- VERSION = '0.1.1'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
@@ -117,5 +117,41 @@ describe SidekiqFieldEncryptor::Server do
117
117
 
118
118
  ok.call('FooJob', message, nil) {}
119
119
  end
120
+
121
+ it 'fails if the serialization methods are different' do
122
+ r = SidekiqFieldEncryptor::Server.new(
123
+ encryption_key: key,
124
+ encrypted_fields: { 'FooJob' => { 1 => true } },
125
+ serialization_method: SidekiqFieldEncryptor::SERIALIZE_JSON
126
+ )
127
+
128
+ e = SidekiqFieldEncryptor::Client.new(
129
+ encryption_key: key,
130
+ encrypted_fields: { 'FooJob' => { 1 => true } },
131
+ serialization_method: SidekiqFieldEncryptor::SERIALIZE_MARHSALL
132
+ )
133
+
134
+ message['args'][1] = e.encrypt(message['args'][1])
135
+ expect { r.call('FooJob', message, nil) {} }
136
+ .to raise_error(/invalid serialization_method/i)
137
+ end
138
+
139
+ it 'allows compat serialization' do
140
+ r = SidekiqFieldEncryptor::Server.new(
141
+ encryption_key: key,
142
+ encrypted_fields: { 'FooJob' => { 1 => true } },
143
+ serialization_method: SidekiqFieldEncryptor::SERIALIZE_JSON,
144
+ serialization_compat: true
145
+ )
146
+
147
+ e = SidekiqFieldEncryptor::Client.new(
148
+ encryption_key: key,
149
+ encrypted_fields: { 'FooJob' => { 1 => true } },
150
+ serialization_method: SidekiqFieldEncryptor::SERIALIZE_MARHSALL
151
+ )
152
+
153
+ message['args'][1] = e.encrypt(message['args'][1])
154
+ r.call('FooJob', message, nil) {}
155
+ end
120
156
  end
121
157
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-field-encryptor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Pettersson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-02 00:00:00.000000000 Z
11
+ date: 2018-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: encryptor
@@ -120,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
120
  version: '0'
121
121
  requirements: []
122
122
  rubyforge_project:
123
- rubygems_version: 2.4.5.1
123
+ rubygems_version: 2.7.6
124
124
  signing_key:
125
125
  specification_version: 4
126
126
  summary: Selectively encrypt fields sent into Sidekiq