lib/kms_encrypted/model.rb in kms_encrypted-0.2.0 vs lib/kms_encrypted/model.rb in kms_encrypted-0.3.0
- old
+ new
@@ -51,26 +51,40 @@
elsif key_id.start_with?("projects/")
# generate random AES-256 key
plaintext_key = OpenSSL::Random.random_bytes(32)
# encrypt it
+ # load client first to ensure namespace is loaded
+ client = KmsEncrypted.google_client
request = ::Google::Apis::CloudkmsV1::EncryptRequest.new(
plaintext: plaintext_key,
additional_authenticated_data: context.to_json
)
- response = KmsEncrypted::Google.kms_client.encrypt_crypto_key(key_id, request)
+ response = client.encrypt_crypto_key(key_id, request)
key_version = response.name
# shorten key to save space
- short_key_id = Base64.encode64(key_version.split("/").select.with_index { |p, i| i.odd? }.join("/"))
+ short_key_id = Base64.encode64(key_version.split("/").select.with_index { |_, i| i.odd? }.join("/"))
# build encrypted key
# we reference the key in the field for easy rotation
encrypted_key = "$gc$#{short_key_id}$#{[response.ciphertext].pack(default_encoding)}"
+ elsif key_id.start_with?("vault/")
+ # generate random AES-256 key
+ plaintext_key = OpenSSL::Random.random_bytes(32)
+
+ # encrypt it
+ response = KmsEncrypted.vault_client.logical.write(
+ "transit/encrypt/#{key_id.sub("vault/", "")}",
+ plaintext: Base64.encode64(plaintext_key),
+ context: Base64.encode64(context.to_json)
+ )
+
+ encrypted_key = response.data[:ciphertext]
else
# generate data key from API
- resp = KmsEncrypted.kms_client.generate_data_key(
+ resp = KmsEncrypted.aws_client.generate_data_key(
key_id: key_id,
encryption_context: context,
key_spec: "AES_256"
)
plaintext_key = resp.plaintext
@@ -90,11 +104,11 @@
key_id: key_id,
context: context
}
ActiveSupport::Notifications.instrument("decrypt_data_key.kms_encrypted", event) do
if encrypted_key.start_with?("insecure-data-key-")
- plaintext_key = "00000000000000000000000000000000"
+ plaintext_key = "00000000000000000000000000000000".encode("BINARY")
elsif encrypted_key.start_with?("$gc$")
_, _, short_key_id, ciphertext = encrypted_key.split("$", 4)
# restore key, except for cryptoKeyVersion
stored_key_id = Base64.decode64(short_key_id).split("/")[0..3]
@@ -102,16 +116,26 @@
stored_key_id.insert(2, "locations")
stored_key_id.insert(4, "keyRings")
stored_key_id.insert(6, "cryptoKeys")
stored_key_id = stored_key_id.join("/")
+ # load client first to ensure namespace is loaded
+ client = KmsEncrypted.google_client
request = ::Google::Apis::CloudkmsV1::DecryptRequest.new(
ciphertext: ciphertext.unpack(default_encoding).first,
additional_authenticated_data: context.to_json
)
- plaintext_key = KmsEncrypted::Google.kms_client.decrypt_crypto_key(stored_key_id, request).plaintext
+ plaintext_key = client.decrypt_crypto_key(stored_key_id, request).plaintext
+ elsif encrypted_key.start_with?("vault:")
+ response = KmsEncrypted.vault_client.logical.write(
+ "transit/decrypt/#{key_id.sub("vault/", "")}",
+ ciphertext: encrypted_key,
+ context: Base64.encode64(context.to_json)
+ )
+
+ plaintext_key = Base64.decode64(response.data[:plaintext])
else
- plaintext_key = KmsEncrypted.kms_client.decrypt(
+ plaintext_key = KmsEncrypted.aws_client.decrypt(
ciphertext_blob: encrypted_key.unpack(default_encoding).first,
encryption_context: context
).plaintext
end
end