Class: Chef::EncryptedAttribute::EncryptedMash::Version2
- Inherits:
-
Version1
- Object
- Mash
- Chef::EncryptedAttribute::EncryptedMash
- Version0
- Version1
- Chef::EncryptedAttribute::EncryptedMash::Version2
- Includes:
- Assertions
- Defined in:
- lib/chef/encrypted_attribute/encrypted_mash/version2.rb
Overview
EncryptedMash Version2 format: using RSA with a shared secret and GCM.
Uses public key cryptography (PKI) to encrypt a shared secret. Then this shared secret is used to encrypt the data using GCM.
- This protocol version is based on the Chef 12 Encrypted Data Bags Version 3 implementation.
- To use it, the following special requirements must be met:
Ruby
>= 2and OpenSSL>= 1.0.1. - This implementation can be improved, is not optimized either for performance or for space.
- Every time the
EncryptedAttributeis updated, all the shared secrets are regenerated.
EncryptedMash::Version2 Structure
If you try to read this encrypted attribute structure, you can see a
Mash attribute with the following content:
EncryptedMash
x_json_classfield is used, with thex_prefix, to be easily integrated with Chef in the future.
EncryptedMash[encrypted_data][data]
The data inside encrypted_data is symmetrically encrypted using the
secret shared key. The data is converted to JSON before the
encryption, then encrypted and finally encoded in base64. By default,
the 'aes-256-gcm' algorithm is used for encryption.
After decryption, the JSON has the following structure:
- In the future, this structure may contain some metadata like default configuration values.
EncryptedMash[encrypted_secret][pub_key_hash1]
The public_key_hash1 key value is the SHA1 of the public key used
for encryption.
Its content is the encrypted shared secret in raw. The encryption is done using the RSA algorithm (PKI).
After decryption, you find the shared secret in raw (in Version1 this is a JSON in base64).
Constant Summary collapse
- ALGORITHM =
Symmetric AEAD algorithm to use by default.
'aes-256-gcm'
Constants inherited from Version1
Chef::EncryptedAttribute::EncryptedMash::Version1::HMAC_ALGORITHM, Chef::EncryptedAttribute::EncryptedMash::Version1::SYMM_ALGORITHM
Constants inherited from Chef::EncryptedAttribute::EncryptedMash
CHEF_TYPE, CHEF_TYPE_VALUE, JSON_CLASS, VERSION_PREFIX
Instance Method Summary collapse
-
#decrypt(key) ⇒ Mixed
Decrypts the current Chef::EncryptedAttribute::EncryptedMash object.
-
#encrypt(value, public_keys) ⇒ EncryptedMash
Encrypts data inside the current Chef::EncryptedAttribute::EncryptedMash object.
-
#initialize(enc_hs = nil) ⇒ Version2
constructor
EncrytpedMash::Version2 constructor.
Methods included from Assertions
#assert_aead_requirements_met!
Methods inherited from Version1
#can_be_decrypted_by?, #needs_update?
Methods inherited from Version0
#can_be_decrypted_by?, #needs_update?
Methods inherited from Chef::EncryptedAttribute::EncryptedMash
create, exist?, exists?, #for_json, json_create, string_to_klass, #to_json, #update_from!, version_klass
Constructor Details
#initialize(enc_hs = nil) ⇒ Version2
EncrytpedMash::Version2 constructor.
Checks that GCM is correctly supported by Ruby and OpenSSL.
112 113 114 115 |
# File 'lib/chef/encrypted_attribute/encrypted_mash/version2.rb', line 112 def initialize(enc_hs = nil) assert_aead_requirements_met!(ALGORITHM) super end |
Instance Method Details
#decrypt(key) ⇒ Mixed
Decrypts the current Chef::EncryptedAttribute::EncryptedMash object.
132 133 134 135 136 137 138 139 140 141 |
# File 'lib/chef/encrypted_attribute/encrypted_mash/version2.rb', line 132 def decrypt(key) key = parse_decryption_key(key) enc_value = self['encrypted_data'].dup # decrypt the shared secret enc_value['secret'] = rsa_decrypt_multi_key(self['encrypted_secret'], key) # decrypt the data value_json = symmetric_decrypt_value(enc_value) json_decode(value_json) end |
#encrypt(value, public_keys) ⇒ EncryptedMash
Encrypts data inside the current Chef::EncryptedAttribute::EncryptedMash object.
118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/chef/encrypted_attribute/encrypted_mash/version2.rb', line 118 def encrypt(value, public_keys) value_json = json_encode(value) public_keys = parse_public_keys(public_keys) # encrypt the data encrypted_data = symmetric_encrypt_value(value_json) # should no include the secret in clear secret = encrypted_data.delete('secret') self['encrypted_data'] = encrypted_data # encrypt the shared secret self['encrypted_secret'] = rsa_encrypt_multi_key(secret, public_keys) self end |