porky_lib 0.1.1 → 0.1.2

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
  SHA1:
3
- metadata.gz: b964b025bbd159e92a88fc03d261abad2903ed7b
4
- data.tar.gz: 15a5a4ef61f2e8db2658cd568379811fcc5d9725
3
+ metadata.gz: 122bad0bf114af2bb03c6aa0373fc443dfe3d9c4
4
+ data.tar.gz: 7f0b09d966c20ba1c223323b8203461f0ca34d5c
5
5
  SHA512:
6
- metadata.gz: 89c5545701a0a866e738dddd32d66ba7c54e0d44e241d261478c5b4fdd94225f1128d7d4dd8d964b8b3fb90f86986291e8db0fbc9a18fb174221f420136502f4
7
- data.tar.gz: 3ec18c9b4aad75e4bb9ca466858c3aa18288e391001bc6ed89050d07e429d68405a061f59a924a2b32079fceae6e46d580ce4f4d2c8df17a84af33a915c837c8
6
+ metadata.gz: 5ad09fc08eb7c6fb8637a29b4805b2fa58ef71716abbad1067ef135b2782737f61ff039988eb7f7dafb647fe3aea76795e96a406bdbab9e0e1bfa56b5259087e
7
+ data.tar.gz: 59bdd3b28bb1d8c24c889749924e4f035971a67427cc3507b7705339b64c5a812218eafcc4ec4a459b2ea62df6d17ebd8311d16ef0eb234915c29dc62eeaf259
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- porky_lib (0.1.1)
4
+ porky_lib (0.1.2)
5
5
  aws-sdk-kms
6
6
  msgpack
7
7
  rbnacl-libsodium
data/README.md CHANGED
@@ -71,8 +71,9 @@ To encrypt data:
71
71
  ```ruby
72
72
  # Where data is the data to encrypt
73
73
  # cmk_key_id is the AWS key ID, Amazon Resource Name (ARN) or alias for the CMK to use to generate the data encryption key (DEK)
74
+ # ciphertext_dek is an optional parameter to specify the data encryption key to use to encrypt the data. If not provided, a new data encryption key will be generated. Default is nil.
74
75
  # encryption_context is an optional parameter to provide additional authentication data for encrypting the DEK. Default is nil.
75
- [ciphertext_dek, ciphertext, nonce] = PorkyLib::Symmetric.instance.encrypt(data, cmk_key_id, encryption_context)
76
+ [ciphertext_dek, ciphertext, nonce] = PorkyLib::Symmetric.instance.encrypt(data, cmk_key_id, ciphertext_dek, encryption_context)
76
77
  ```
77
78
 
78
79
  ### Decrypting Data
@@ -85,6 +86,29 @@ To decrypt data:
85
86
  plaintext_data = PorkyLib::Symmetric.instance.decrypt(ciphertext_dek, ciphertext, nonce, encryption_context)
86
87
  ```
87
88
 
89
+ ### Generating Data Encryption Keys
90
+ To generate a new data encryption key:
91
+ ```ruby
92
+ # Where cmk_key_id is the AWS key ID, Amazon Resource Name (ARN) or alias for the CMK to use to generate the data encryption key (DEK)
93
+ # encryption_context is an optional parameter to provide additional authentication data for encrypting the DEK. Default is nil.
94
+ plaintext_key, ciphertext_key = PorkyLib::Symmetric.instance.generate_data_encryption_key(cmk_key_id, encryption_context)
95
+ ```
96
+
97
+ ### Decrypting Data Encryption Keys
98
+ To decrypt an existing ciphertext data encryption key:
99
+ ```ruby
100
+ # Where ciphertext_key is the data encryption key, encrypted by a CMK within your AWS environment.
101
+ # encryption_context is an optional parameter to provide additional authentication data for encrypting the DEK. Default is nil.
102
+ plaintext_key = PorkyLib::Symmetric.instance.generate_data_encryption_key(ciphertext_key, encryption_context)
103
+ ```
104
+
105
+ ### Securely Deleting Plaintext Key From Memory
106
+ To securely delete the plaintext key from memory:
107
+ ```ruby
108
+ # Where length is the number of bytes of the plaintext key (i.e. plaintext_key.bytesize)
109
+ plaintext_key = PorkyLib::Symmetric.instance.secure_delete_plaintext_key(plaintext_key.bytesize)
110
+ ```
111
+
88
112
  ## Development
89
113
 
90
114
  Development on this project should occur on separate feature branches and pull requests should be submitted. When submitting a
@@ -40,25 +40,35 @@ class PorkyLib::Symmetric
40
40
  client.create_alias(target_key_id: key_id, alias_name: key_alias)
41
41
  end
42
42
 
43
- def encrypt(data, cmk_key_id, encryption_context = nil)
44
- return if data.nil? || cmk_key_id.nil?
45
-
46
- # Generate a new data encryption key
43
+ def generate_data_encryption_key(cmk_key_id, encryption_context = nil)
47
44
  PorkyLib::Config.logger.info('Generating new data encryption key')
48
-
49
45
  resp = {}
50
46
  resp = client.generate_data_key(key_id: cmk_key_id, key_spec: SYMMETRIC_KEY_SPEC, encryption_context: encryption_context) if encryption_context
51
47
  resp = client.generate_data_key(key_id: cmk_key_id, key_spec: SYMMETRIC_KEY_SPEC) unless encryption_context
52
48
 
53
- plaintext_key = resp.to_h[:plaintext]
54
- ciphertext_key = resp.to_h[:ciphertext_blob]
49
+ [resp.to_h[:plaintext], resp.to_h[:ciphertext_blob]]
50
+ end
51
+
52
+ def decrypt_data_encryption_key(ciphertext_key, encryption_context = nil)
53
+ PorkyLib::Config.logger.info('Decrypting data encryption key')
54
+
55
+ return client.decrypt(ciphertext_blob: ciphertext_key, encryption_context: encryption_context).to_h[:plaintext] if encryption_context
56
+ client.decrypt(ciphertext_blob: ciphertext_key).to_h[:plaintext]
57
+ end
58
+
59
+ def encrypt(data, cmk_key_id, ciphertext_dek = nil, encryption_context = nil)
60
+ return if data.nil? || cmk_key_id.nil?
61
+
62
+ # Generate a new data encryption key or decrypt existing key, if provided
63
+ plaintext_key = decrypt_data_encryption_key(ciphertext_dek, encryption_context) if ciphertext_dek
64
+ ciphertext_key = ciphertext_dek if ciphertext_dek
65
+ plaintext_key, ciphertext_key = generate_data_encryption_key(cmk_key_id, encryption_context) unless ciphertext_dek
55
66
 
56
67
  # Initialize the box
57
68
  secret_box = RbNaCl::SecretBox.new(plaintext_key)
58
69
 
59
- # rubocop:disable Lint/UselessAssignment
60
- plaintext_key = "\0" * plaintext_key.bytesize
61
- # rubocop:enable Lint/UselessAssignment
70
+ # Securely delete the plaintext value from memory
71
+ plaintext_key.replace(secure_delete_plaintext_key(plaintext_key.bytesize))
62
72
 
63
73
  # First, make a nonce: A single-use value never repeated under the same key
64
74
  # The nonce isn't secret, and can be sent with the ciphertext.
@@ -76,23 +86,20 @@ class PorkyLib::Symmetric
76
86
  return if ciphertext.nil? || ciphertext_dek.nil? || nonce.nil?
77
87
 
78
88
  # Decrypt the data encryption key
79
- PorkyLib::Config.logger.info('Decrypting data encryption key')
80
-
81
- resp = {}
82
- resp = client.decrypt(ciphertext_blob: ciphertext_dek, encryption_context: encryption_context) if encryption_context
83
- resp = client.decrypt(ciphertext_blob: ciphertext_dek) unless encryption_context
84
-
85
- plaintext_key = resp.to_h[:plaintext]
89
+ plaintext_key = decrypt_data_encryption_key(ciphertext_dek, encryption_context)
86
90
 
87
91
  secret_box = RbNaCl::SecretBox.new(plaintext_key)
88
92
 
89
- # rubocop:disable Lint/UselessAssignment
90
- plaintext_key = "\0" * plaintext_key.bytesize
91
- # rubocop:enable Lint/UselessAssignment
93
+ # Securely delete the plaintext value from memory
94
+ plaintext_key.replace(secure_delete_plaintext_key(plaintext_key.bytesize))
92
95
 
93
96
  PorkyLib::Config.logger.info('Beginning decryption')
94
97
  result = secret_box.decrypt(nonce, ciphertext)
95
98
  PorkyLib::Config.logger.info('Decryption complete')
96
99
  result
97
100
  end
101
+
102
+ def secure_delete_plaintext_key(length)
103
+ "\0" * length
104
+ end
98
105
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PorkyLib
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: porky_lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Fletcher
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-07-13 00:00:00.000000000 Z
11
+ date: 2018-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler