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
>= 2
and OpenSSL>= 1.0.1
. - This implementation can be improved, is not optimized either for performance or for space.
- Every time the
EncryptedAttribute
is 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
├── chef_type: "encrypted_attribute" (string).
├── x_json_class: The used `EncryptedMash` version class name (string).
├── encrypted_data
│ ├── cipher: The used PKI algorithm, "aes-256-gcm" (string).
│ ├── data: PKI encrypted data (base64).
│ ├── auth_tag: GCM authentication tag (base64).
│ └── iv: Initialization vector (in base64).
└── encrypted_secret
├── pub_key_hash1: The shared secret encrypted for the public key 1
│ (base64).
├── pub_key_hash2: The shared secret encrypted for the public key 2
│ (base64).
└── ...
x_json_class
field 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:
└── encrypted_data
└── data (symmetrically encrypted JSON in base64)
└── content: attribute content as a Mash.
- 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 |