在 Ruby 中从 aws-kms 解密密钥

Decrypting keys from aws-kms in Ruby

我在无服务器框架上使用 serverless-kms-secrets 来设置一些我想使用 Ruby 使用的 ENV 变量。

我可以确认插件完美运行,它生成了带有加密变量的文件,我可以在我的 AWS lambda 环境中看到加密变量。 问题是我无法在Ruby中解密。在插件中(正确)解密它的代码是 here,我知道它获取保存在文件中的字符串并使用 Base64 对其进行编码,所以没什么大不了的。 在 Ruby:

token = "blablabla"
client = Aws::KMS::Client.new(region: 'us-east-1')
blob = Base64.encode64(token)
client.decrypt({ciphertext_blob: blob})
....
Aws::KMS::Errors::InvalidCiphertextException ()

客户端应该会自动获取我的凭据,但我不确定我是否理解 keyArn 的使用方式,虽然看起来不相关。

有人知道如何解决这个问题吗?

它看起来像 Aws::KMS::Client#decrypt expects a binary string that includes the encrypted Ciphertext that you want to decrypt 中的 ciphertext_blob 参数。

在您的示例中,您将 未加密的 Base64 编码字符串 传递到 decrypt。相反,您需要传入一个 加密的二进制字符串 .

要获得加密的字符串,我们可以使用您的密钥 ID(也称为您的 ARN)和您要以明文形式加密的字符串调用 Aws::KMS::Client#encrypt

在该调用的响应中,我们返回一个 ciphertext_blob,这是我们解码时需要使用的加密二进制字符串。

有时您可能会看到二进制数据 "unpacked",您可以演示如何做 ciphertext_blob.unpack('H*')。如果您有解包数据并想解密它,您将需要对其进行打包:encrypted_upacked_blob.pack('H*').

下面是明文字符串往返编码和解码的完整示例:

require 'aws-sdk-kms'

client = Aws::KMS::Client.new

key_id = 'arn:aws:kms:us-east-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'

plaintext_to_encrypt = 'blablabla'

encrypt_response = client.encrypt({
  key_id: key_id,
  plaintext: plaintext_to_encrypt,
})

encrypt_response.ciphertext_blob
# => "\x01\x02\x02\x00xt/Jyu\x85B\xCA\x16v\xDAa3DM1$\e8Y\xF9\x812\x1E\xA9\xD3\xE3R\x1E/}\xCA\x...

encrypted_upacked_blob = encrypt_response.ciphertext_blob.unpack('H*')
# => ["0102020078742f4a79758542ca1676da6133444d31241b3859f981321ea9d3e3521e2f7dca01a7f89f2ee03...

encrypted_packed_blob = encrypted_upacked_blob.pack('H*')
# => "\x01\x02\x02\x00xt/Jyu\x85B\xCA\x16v\xDAa3DM1$\e8Y\xF9\x812\x1E\xA9\xD3\xE3R\x1E/}\xCA\x...

decrypt_response = client.decrypt({
  ciphertext_blob: encrypted_packed_blob
})

decrypted_plaintext = decrypt_response.plaintext
# => "blablabla"

这个例子结合了AWS提供的两个例子:Encrypting Data in AWS KMS using Ruby SDK and Decrypting a Data Blob in AWS KMS.

为了更好地了解 [blob].pack("H*") 正在做什么,请查看 this Whosebug post and Ruby's Array#pack 文档。

我没有对字符串进行编码,而是对其进行了解码。

token = "blablabla"
client = Aws::KMS::Client.new(region: 'us-east-1')
blob = Base64.decode64(token)
client.decrypt({ciphertext_blob: blob})