加密和解密数据密钥 - Amazon Key Management Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

加密和解密数据密钥

本主题中的示例使用 Amazon KMS API 中的 EncryptDecryptReEncrypt 操作。

这些操作专用于加密和解密数据密钥。它们在加密操作中使用 Amazon KMS keys,而且它们无法接受 4KB(4096 字节)以上的数据。尽管您可以使用它们来加密少量数据,例如密码或 RSA 密钥,但它们不用于加密应用程序数据。

要加密应用程序数据,请使用 Amazon 服务的服务器端加密功能或客户端加密库,例如 Amazon Encryption SDKAmazon S3 加密客户端

加密数据密钥

Encrypt 操作专用于加密数据密钥,但并不常用。GenerateDataKeyGenerateDataKeyWithoutPlaintext 操作会返回加密的数据密钥。在将加密的数据移动到不同区域并希望在新区域中使用 KMS 密钥加密其数据密钥时,可以使用此方法。

在需要客户端对象的语言中,这些示例使用您在 Amazon KMS 中创建的 创建客户端 客户端对象。

Java

有关详细信息,请参阅 Amazon SDK for Java API 参考中的 encrypt 方法

// Encrypt a data key // // Replace the following example key ARN with any valid key identfier String keyId = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"; ByteBuffer plaintext = ByteBuffer.wrap(new byte[]{1,2,3,4,5,6,7,8,9,0}); EncryptRequest req = new EncryptRequest().withKeyId(keyId).withPlaintext(plaintext); ByteBuffer ciphertext = kmsClient.encrypt(req).getCiphertextBlob();
C#

有关详细信息,请参阅 https://docs.amazonaws.cn/sdkfornet/v3/apidocs/items/KeyManagementService/MKeyManagementServiceEncryptEncryptRequest.html 中的 Amazon SDK for .NETEncrypt 方法

// Encrypt a data key // // Replace the following example key ARN with any valid key identfier String keyId = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"; MemoryStream plaintext = new MemoryStream(); plaintext.Write(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }, 0, 10); EncryptRequest encryptRequest = new EncryptRequest() { KeyId = keyId, Plaintext = plaintext }; MemoryStream ciphertext = kmsClient.Encrypt(encryptRequest).CiphertextBlob;
Python

有关详细信息,请参阅 中的 encrypt 方法Amazon SDK for Python (Boto3)。

# Encrypt a data key # Replace the following example key ARN with any valid key identfier key_id = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab' plaintext = b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00' response = kms_client.encrypt( KeyId=key_id, Plaintext=plaintext ) ciphertext = response['CiphertextBlob']
Ruby

有关详细信息,请参阅 https://docs.amazonaws.cn/sdk-for-ruby/v3/api/Aws/KMS/Client.html#encrypt-instance_method 中的 Amazon SDK for Rubyencrypt 实例方法。

# Encrypt a data key # Replace the following example key ARN with any valid key identfier key_id = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab' plaintext = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00" response = kmsClient.encrypt({ key_id: key_id, plaintext: plaintext }) ciphertext = response.ciphertext_blob
PHP

有关详细信息,请参阅 https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-kms-2014-11-01.html#encrypt 中的 Amazon SDK for PHPEncrypt 方法

// Encrypt a data key // // Replace the following example key ARN with any valid key identfier $keyId = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'; $message = pack('c*',1,2,3,4,5,6,7,8,9,0); $result = $KmsClient->encrypt([ 'KeyId' => $keyId, 'Plaintext' => $message, ]); $ciphertext = $result['CiphertextBlob'];
Node.js

有关详细信息,请参阅适用于 Node.js 中的 JavaScript 的 Amazon 开发工具包中的 encrypt 属性

// Encrypt a data key // // Replace the following example key ARN with any valid key identfier const KeyId = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'; const Plaintext = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]); kmsClient.encrypt({ KeyId, Plaintext }, (err, data) => { if (err) console.log(err, err.stack); // an error occurred else { const { CiphertextBlob } = data; ... } });
PowerShell

要在 KMS 密钥下加密数据密钥,请使用 Invoke-KMSEncrypt cmdlet。它将密文作为 MemoryStream (System.IO.MemoryStream) 对象返回。您可以使用 MemoryStream 对象作为 Invoke-KMSDecrypt cmdlet 的输入。

Amazon KMS 也将数据密钥作为 MemoryStream 对象返回。在这个例子中,为了模拟明文数据密钥,我们创建一个字节数组并将其写入 MemoryStream 对象。

请注意,PlaintextInvoke-KMSEncrypt 参数采用字节数组 (byte[]);它不需要 MemoryStream 对象。从 AWSPWShell 版本 4.0 开始,所有 AWSPowerShell 模块中接受字节数组和 MemoryStream 对象的参数都接受字节数组、MemoryStream 对象、字符串、字符串数组和 FileInfo (System.IO.FileInfo) 对象。您可以将这些类型中的任何一种传递给 Invoke-KMSEncrypt

# Encrypt a data key # Replace the following example key ARN with any valid key identfier $keyId = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab' # Simulate a data key # Create a byte array [byte[]] $bytes = 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 # Create a MemoryStream $plaintext = [System.IO.MemoryStream]::new() # Add the byte array to the MemoryStream $plaintext.Write($bytes, 0, $bytes.length) # Encrypt the simulated data key $response = Invoke-KMSEncrypt -KeyId $keyId -Plaintext $plaintext # Get the ciphertext from the response $ciphertext = $response.CiphertextBlob

要使用 Amazon KMS PowerShell cmdlets,请安装 AWS.Tools.KeyManagementService 模块。有关更多信息,请参阅 Amazon Tools for Windows PowerShell 用户指南

解密数据密钥

要解密数据密钥,请使用 Decrypt 操作。

您指定的 ciphertextBlob 必须是来自 GenerateDataKeyGenerateDataKeyWithoutPlaintextEncrypt 响应的 CiphertextBlob 字段的值,或来自 GenerateDataKeyPairGenerateDataKeyPairWithoutPlaintext 响应的 PrivateKeyCiphertextBlob 字段的值。您还可以使用 Decrypt 操作解密由非对称 KMS 密钥中的公有密钥在 Amazon KMS 外部加密的数据。

使用对称 KMS 密钥进行解密时不需要 KeyId 参数。Amazon KMS 可以获取用于加密密文 Blob 中的元数据中的数据的 KMS 密钥。但是,指定您正在使用的 KMS 密钥始终是最佳实践。此做法可确保您使用预期的 KMS 密钥,并防止您意外使用不信任的 KMS 密钥解密密文。

在需要客户端对象的语言中,这些示例使用您在 Amazon KMS 中创建的 创建客户端 客户端对象。

Java

有关详细信息,请参阅 Amazon SDK for Java API 参考中的 decrypt 方法

// Decrypt a data key // // Replace the following example key ARN with any valid key identfier String keyId = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"; ByteBuffer ciphertextBlob = Place your ciphertext here; DecryptRequest req = new DecryptRequest().withCiphertextBlob(ciphertextBlob).withKeyId(keyId); ByteBuffer plainText = kmsClient.decrypt(req).getPlaintext();
C#

有关详细信息,请参阅 https://docs.amazonaws.cn/sdkfornet/v3/apidocs/items/KeyManagementService/MKeyManagementServiceDecryptDecryptRequest.html 中的 Amazon SDK for .NETDecrypt 方法

// Decrypt a data key // // Replace the following example key ARN with any valid key identfier String keyId = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"; MemoryStream ciphertextBlob = new MemoryStream(); // Write ciphertext to memory stream DecryptRequest decryptRequest = new DecryptRequest() { CiphertextBlob = ciphertextBlob, KeyId = keyId }; MemoryStream plainText = kmsClient.Decrypt(decryptRequest).Plaintext;
Python

有关详细信息,请参阅 中的 decrypt 方法Amazon SDK for Python (Boto3)。

# Decrypt a data key # Replace the following example key ARN with any valid key identfier key_id = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab' ciphertext = 'Place your ciphertext here' response = kms_client.decrypt( CiphertextBlob=ciphertext, KeyId=key_id ) plaintext = response['Plaintext']
Ruby

有关详细信息,请参阅 https://docs.amazonaws.cn/sdk-for-ruby/v3/api/Aws/KMS/Client.html#decrypt-instance_method 中的 Amazon SDK for Rubydecrypt 实例方法。

# Decrypt a data key # Replace the following example key ARN with any valid key identfier key_id = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab' ciphertext = 'Place your ciphertext here' ciphertext_packed = [ciphertext].pack("H*") response = kmsClient.decrypt({ ciphertext_blob: ciphertext_packed, key_id: key_id }) plaintext = response.plaintext
PHP

有关详细信息,请参阅 https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-kms-2014-11-01.html#decrypt 中的 Amazon SDK for PHPDecrypt 方法

// Decrypt a data key // // Replace the following example key ARN with any valid key identfier $keyId = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'; $ciphertext = 'Place your cipher text blob here'; $result = $KmsClient->decrypt([ 'CiphertextBlob' => $ciphertext, 'KeyId' => $keyId, ]); $plaintext = $result['Plaintext'];
Node.js

有关详细信息,请参阅适用于 Node.js 中的 JavaScript 的 Amazon 开发工具包中的 decrypt 属性

// Decrypt a data key // // Replace the following example key ARN with any valid key identfier const KeyId = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'; const CiphertextBlob = 'Place your cipher text blob here'; kmsClient.decrypt({ CiphertextBlob, KeyId }, (err, data) => { if (err) console.log(err, err.stack); // an error occurred else { const { Plaintext } = data; ... } });
PowerShell

要解密数据密钥,请使用 Invoke-KMSEncrypt cmdlet。

此 cmdlet 以 MemoryStream (System.IO.MemoryStream) 对象的形式返回明文。要将其转换为字节数组,请使用将 MemoryStream 对象转换为字节数组的 cmdlet 或函数,例如 Convert 模块中的函数。

由于此示例使用 Amazon KMS 加密 cmdlet 返回的密文,因此它使用 MemoryStream 对象作为 CiphertextBlob 参数的值。但是,CiphertextBlobInvoke-KMSDecrypt 参数采用字节数组 (byte[]);它不需要 MemoryStream 对象。从 AWSPWShell 版本 4.0 开始,所有 AWSPowerShell 模块中接受字节数组和 MemoryStream 对象的参数都接受字节数组、MemoryStream 对象、字符串、字符串数组和 FileInfo (System.IO.FileInfo) 对象。您可以将这些类型中的任何一种传递给 Invoke-KMSDecrypt

# Decrypt a data key # Replace the following example key ARN with any valid key identfier $keyId = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab' [System.IO.MemoryStream]$ciphertext = Read-Host 'Place your cipher text blob here' $response = Invoke-KMSDecrypt -CiphertextBlob $ciphertext -KeyId $keyId $plaintext = $response.Plaintext

要使用 Amazon KMS PowerShell cmdlets,请安装 AWS.Tools.KeyManagementService 模块。有关更多信息,请参阅 Amazon Tools for Windows PowerShell 用户指南

在不同的 Amazon KMS key 下重新加密数据密钥

要解密已加密数据密钥,然后立即在其他 Amazon KMS key 下重新加密该数据密钥,请使用 ReEncrypt 操作。这些操作全部都在 Amazon KMS 内的服务器端执行,因此它们永远不会将您的明文在 Amazon KMS 外公开。

您指定的 ciphertextBlob 必须是来自 GenerateDataKeyGenerateDataKeyWithoutPlaintextEncrypt 响应的 CiphertextBlob 字段的值,或来自 GenerateDataKeyPairGenerateDataKeyPairWithoutPlaintext 响应的 PrivateKeyCiphertextBlob 字段的值。您还可以使用 ReEncrypt 操作重新加密由非对称 KMS 密钥中的公有密钥在 Amazon KMS 外部加密的数据。

使用对称 KMS 密钥进行重新加密时不需要 SourceKeyId 参数。Amazon KMS 可以获取用于加密密文 Blob 中的元数据中的数据的 KMS 密钥。但是,指定您正在使用的 KMS 密钥始终是最佳实践。此做法可确保您使用预期的 KMS 密钥,并防止您意外使用不信任的 KMS 密钥解密密文。

在需要客户端对象的语言中,这些示例使用您在 Amazon KMS 中创建的 创建客户端 客户端对象。

Java

有关详细信息,请参阅 Amazon SDK for Java API 参考中的 reEncrypt 方法

// Re-encrypt a data key ByteBuffer sourceCiphertextBlob = Place your ciphertext here; // Replace the following example key ARNs with valid key identfiers String sourceKeyId = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"; String destinationKeyId = "arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321"; ReEncryptRequest req = new ReEncryptRequest(); req.setCiphertextBlob(sourceCiphertextBlob); req.setSourceKeyId(sourceKeyId); req.setDestinationKeyId(destinationKeyId); ByteBuffer destinationCipherTextBlob = kmsClient.reEncrypt(req).getCiphertextBlob();
C#

有关详细信息,请参阅 https://docs.amazonaws.cn/sdkfornet/v3/apidocs/items/KeyManagementService/MKeyManagementServiceReEncryptReEncryptRequest.html 中的 Amazon SDK for .NETReEncrypt 方法

// Re-encrypt a data key MemoryStream sourceCiphertextBlob = new MemoryStream(); // Write ciphertext to memory stream // Replace the following example key ARNs with valid key identfiers String sourceKeyId = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"; String destinationKeyId = "arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321"; ReEncryptRequest reEncryptRequest = new ReEncryptRequest() { CiphertextBlob = sourceCiphertextBlob, SourceKeyId = sourceKeyId, DestinationKeyId = destinationKeyId }; MemoryStream destinationCipherTextBlob = kmsClient.ReEncrypt(reEncryptRequest).CiphertextBlob;
Python

有关详细信息,请参阅 中的 re_encrypt 方法Amazon SDK for Python (Boto3)。

# Re-encrypt a data key ciphertext = 'Place your ciphertext here' # Replace the following example key ARNs with valid key identfiers source_key_id = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab' destination_key_id = 'arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321' response = kms_client.re_encrypt( CiphertextBlob=ciphertext, SourceKeyId=source_key_id, DestinationKeyId=destination_key_id ) destination_ciphertext_blob = response['CiphertextBlob']
Ruby

有关详细信息,请参阅 https://docs.amazonaws.cn/sdk-for-ruby/v3/api/Aws/KMS/Client.html#re_encrypt-instance_method 中的 Amazon SDK for Rubyre_encrypt 实例方法。

# Re-encrypt a data key ciphertext = 'Place your ciphertext here' ciphertext_packed = [ciphertext].pack("H*") # Replace the following example key ARNs with valid key identfiers source_key_id = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab' destination_key_id = 'arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321' response = kmsClient.re_encrypt({ ciphertext_blob: ciphertext_packed, source_key_id: source_key_id, destination_key_id: destination_key_id }) destination_ciphertext_blob = response.ciphertext_blob.unpack('H*')
PHP

有关详细信息,请参阅 https://docs.amazonaws.cn/aws-sdk-php/v3/api/api-kms-2014-11-01.html#reencrypt 中的 Amazon SDK for PHPReEncrypt 方法

// Re-encrypt a data key $ciphertextBlob = 'Place your ciphertext here'; // Replace the following example key ARNs with valid key identfiers $sourceKeyId = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'; $destinationKeyId = 'arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321'; $result = $KmsClient->reEncrypt([ 'CiphertextBlob' => $ciphertextBlob, 'SourceKeyId' => $sourceKeyId, 'DestinationKeyId' => $destinationKeyId, ]);
Node.js

有关详细信息,请参阅适用于 Node.js 中的 JavaScript 的 Amazon 开发工具包中的 reEncrypt 属性

// Re-encrypt a data key const CiphertextBlob = 'Place your cipher text blob here'; // Replace the following example key ARNs with valid key identfiers const SourceKeyId = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'; const DestinationKeyId = 'arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321'; kmsClient.reEncrypt({ CiphertextBlob, SourceKeyId, DestinationKeyId }, (err, data) => { ... });
PowerShell

要以相同或不同的 KMS 密钥重新加密密文,请使用 Invoke-KMSReEncrypt cmdlet。

由于此示例使用 Amazon KMS 加密 cmdlet 返回的密文,因此它使用 MemoryStream 对象作为 CiphertextBlob 参数的值。但是,CiphertextBlobInvoke-KMSReEncrypt 参数采用字节数组 (byte[]);它不需要 MemoryStream 对象。从 AWSPWShell 版本 4.0 开始,所有 AWSPowerShell 模块中接受字节数组和 MemoryStream 对象的参数都接受字节数组、MemoryStream 对象、字符串、字符串数组和 FileInfo (System.IO.FileInfo) 对象。您可以将这些类型中的任何一种传递给 Invoke-KMSReEncrypt

# Re-encrypt a data key [System.IO.MemoryStream]$ciphertextBlob = Read-Host 'Place your cipher text blob here' # Replace the following example key ARNs with valid key identfiers $sourceKeyId = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab' $destinationKeyId = 'arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321' $response = Invoke-KMSReEncrypt -Ciphertext $ciphertextBlob -SourceKeyId $sourceKeyId -DestinationKeyId $destinationKeyId $reEncryptedCiphertext = $response.CiphertextBlob

要使用 Amazon KMS PowerShell cmdlets,请安装 AWS.Tools.KeyManagementService 模块。有关更多信息,请参阅 Amazon Tools for Windows PowerShell 用户指南