porky_lib 0.1.1 → 0.1.2

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 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