原始 AES 密钥环 - AWS Encryption SDK

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

原始 AES 密钥环

AWS Encryption SDK 允许您使用您提供的 AES 对称密钥作为包装密钥来保护您的数据密钥。您需要生成、存储和保护密钥材料,最好是在硬件安全模块(HSM)或密钥管理系统中操作。如果您需要提供包装密钥并在本地或离线加密数据密钥,则请使用原始 AES 密钥环。

原始 AES 密钥环使用 AES-GCM 算法以及您指定为字节数组的包装密钥对数据进行加密。每个原始 AES 密钥环中只能指定一个包装密钥,但每个多重密钥环中可以包含多个原始 AES 密钥环,该等密钥环可单独纳入或与其他密钥环一同纳入。

当 AES 加密密钥与 AES 加密密钥一起使用 AWS Encryption SDK for Python 时,Raw AES 密钥环等同于 AWS Encryption SDK for Java 和中的RawMasterKey类并与该类互操作。JceMasterKey您可以使用一种实现加密数据,用使用相同包装密钥的任何其他实现进行解密。有关详细信息,请参阅密钥环兼容性

密钥命名空间和名称

为标识密钥环中的 AES 密钥,原始 AES 密钥环使用您提供的密钥命名空间密钥名称。这些值不是机密的。其以明文形式出现在加密操作返回的加密消息的标头中。我们建议在 HSM 或密钥管理系统中使用密钥命名空间与用于标识该系统中 AES 密钥的密钥名称。

注意

密钥命名空间和密钥名称等同于 JceMasterKeyRawMasterKey提供程序 ID(或提供程序)和密钥 ID字段。

.NET AWS Encryption SDK 的 AWS Encryption SDK for C 和保留 KMS aws-kms 密钥的密钥命名空间值。请勿在包含这些库的原始 AES 密钥环或原始 RSA 密钥环中使用此命名空间值。

如果您通过构造不同的密钥环加密和解密给定消息,命名空间和名称值则至关重要。如果解密密钥环中的密钥命名空间和密钥名称与加密密钥环中的密钥命名空间和密钥名称不完全匹配、大小写不一致,即使密钥材料字节数相同,也不会使用解密密钥环。

例如,您可以使用密钥命名空间 HSM_01 和密钥名称 AES_256_012 定义原始 AES 密钥环。然后使用该密钥环加密部分数据。要解密这些数据,请使用相同的密钥命名空间、密钥名称和密钥材料构造原始 AES 密钥环。

以下示例说明了如何创建原始 AES 密钥。AESWrappingKey 变量代表您提供的密钥材料。

C

要在中实例化 Raw AES 密钥环, AWS Encryption SDK for C请使用。aws_cryptosdk_raw_aes_keyring_new()有关完整示例,请参阅 raw_aes_keyring.c

struct aws_allocator *alloc = aws_default_allocator(); AWS_STATIC_STRING_FROM_LITERAL(wrapping_key_namespace, "HSM_01"); AWS_STATIC_STRING_FROM_LITERAL(wrapping_key_name, "AES_256_012"); struct aws_cryptosdk_keyring *raw_aes_keyring = aws_cryptosdk_raw_aes_keyring_new( alloc, wrapping_key_namespace, wrapping_key_name, aes_wrapping_key, wrapping_key_len);
C# / .NET

要在 AWS Encryption SDK 中为.NET 创建原始 AES 密钥环,请使用materialProviders.CreateRawAesKeyring()方法。有关完整的示例,请参阅 Raw AESKeyring Example.cs

以下示例使用适用于 .NET 的 AWS Encryption SDK 版本 4.x

// Instantiate the AWS Encryption SDK and material providers var esdk = new ESDK(new AwsEncryptionSdkConfig()); var mpl = new MaterialProviders(new MaterialProvidersConfig()); var keyNamespace = "HSM_01"; var keyName = "AES_256_012"; // This example uses the key generator in Bouncy Castle to generate the key material. // In production, use key material from a secure source. var aesWrappingKey = new MemoryStream(GeneratorUtilities.GetKeyGenerator("AES256").GenerateKey()); // Create the keyring that determines how your data keys are protected. var createKeyringInput = new CreateRawAesKeyringInput { KeyNamespace = keyNamespace, KeyName = keyName, WrappingKey = aesWrappingKey, WrappingAlg = AesWrappingAlg.ALG_AES256_GCM_IV12_TAG16 }; var keyring = materialProviders.CreateRawAesKeyring(createKeyringInput);
JavaScript Browser

浏览器 AWS Encryption SDK for JavaScript 中的从 API 中获取其加密原语。WebCrypto在构造密钥环之前,必须使用RawAesKeyringWebCrypto.importCryptoKey()将原始密钥材料导入 WebCrypto 后端。这样可以确保即使对的所有调用都是异步的,密钥环也是完整 WebCrypto 的。

然后,要实例化原始 AES 密钥环,请使用 RawAesKeyringWebCrypto() 方法。您必须根据密钥材料的长度指定 AES 包装算法(“包装套件”)。有关完整的示例,请参阅 aes_simple.ts(浏览器)。JavaScript

以下示例使用buildClient函数来指定默认的承诺策略REQUIRE_ENCRYPT_REQUIRE_DECRYPT。您也可以使用buildClient来限制加密消息中加密数据密钥的数量。有关更多信息,请参阅 限制加密数据密钥

import { RawAesWrappingSuiteIdentifier, RawAesKeyringWebCrypto, synchronousRandomValues, buildClient, CommitmentPolicy, } from '@aws-crypto/client-browser' const { encrypt, decrypt } = buildClient( CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT ) const keyNamespace = 'HSM_01' const keyName = 'AES_256_012' const wrappingSuite = RawAesWrappingSuiteIdentifier.AES256_GCM_IV12_TAG16_NO_PADDING /* Import the plaintext AES key into the WebCrypto backend. */ const aesWrappingKey = await RawAesKeyringWebCrypto.importCryptoKey( rawAesKey, wrappingSuite ) const rawAesKeyring = new RawAesKeyringWebCrypto({ keyName, keyNamespace, wrappingSuite, aesWrappingKey })
JavaScript Node.js

要在 for Node.js 中实例化 Raw AES 密钥环,请创建该 AWS Encryption SDK for JavaScript 类的实例。 RawAesKeyringNode您必须根据密钥材料的长度指定 AES 包装算法(“包装套件”)。有关完整的示例,请参阅 aes_simple.ts (Node.js)。JavaScript

以下示例使用buildClient函数来指定默认的承诺策略REQUIRE_ENCRYPT_REQUIRE_DECRYPT。您也可以使用buildClient来限制加密消息中加密数据密钥的数量。有关更多信息,请参阅 限制加密数据密钥

import { RawAesKeyringNode, buildClient, CommitmentPolicy, RawAesWrappingSuiteIdentifier, } from '@aws-crypto/client-node' const { encrypt, decrypt } = buildClient( CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT ) const keyName = 'AES_256_012' const keyNamespace = 'HSM_01' const wrappingSuite = RawAesWrappingSuiteIdentifier.AES256_GCM_IV12_TAG16_NO_PADDING const rawAesKeyring = new RawAesKeyringNode({ keyName, keyNamespace, aesWrappingKey, wrappingSuite, })
Java

要在中实例化 Raw AES 密钥环, AWS Encryption SDK for Java请使用。matProv.CreateRawAesKeyring()

final CreateRawAesKeyringInput keyringInput = CreateRawAesKeyringInput.builder() .keyName("AES_256_012") .keyNamespace("HSM_01") .wrappingKey(AESWrappingKey) .wrappingAlg(AesWrappingAlg.ALG_AES256_GCM_IV12_TAG16) .build(); final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); IKeyring rawAesKeyring = matProv.CreateRawAesKeyring(keyringInput);
Python

以下示例使用默认承诺策略实例化 AWS Encryption SDK 客户端。REQUIRE_ENCRYPT_REQUIRE_DECRYPT有关完整示例,请参阅中 AWS Encryption SDK for Python 存储库中的 raw_aes_keyring_example.py GitHub。

# Instantiate the AWS Encryption SDK client client = aws_encryption_sdk.EncryptionSDKClient( commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT ) # Define the key namespace and key name key_name_space = "HSM_01" key_name = "AES_256_012" # Optional: Create an encryption context encryption_context: Dict[str, str] = { "encryption": "context", "is not": "secret", "but adds": "useful metadata", "that can help you": "be confident that", "the data you are handling": "is what you think it is", } # Instantiate the material providers mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders( config=MaterialProvidersConfig() ) # Create Raw AES keyring keyring_input: CreateRawAesKeyringInput = CreateRawAesKeyringInput( key_namespace=key_name_space, key_name=key_name, wrapping_key=AESWrappingKey, wrapping_alg=AesWrappingAlg.ALG_AES256_GCM_IV12_TAG16 ) raw_aes_keyring: IKeyring = mat_prov.create_raw_aes_keyring( input=keyring_input )
Rust
// Instantiate the AWS Encryption SDK client let esdk_config = AwsEncryptionSdkConfig::builder().build()?; let esdk_client = esdk_client::Client::from_conf(esdk_config)?; // Define the key namespace and key name let key_namespace: &str = "HSM_01"; let key_name: &str = "AES_256_012"; // Optional: Create an encryption context let encryption_context = HashMap::from([ ("encryption".to_string(), "context".to_string()), ("is not".to_string(), "secret".to_string()), ("but adds".to_string(), "useful metadata".to_string()), ("that can help you".to_string(), "be confident that".to_string()), ("the data you are handling".to_string(), "is what you think it is".to_string()), ]); // Instantiate the material providers library let mpl_config = MaterialProvidersConfig::builder().build()?; let mpl = mpl_client::Client::from_conf(mpl_config)?; // Create Raw AES keyring let raw_aes_keyring = mpl .create_raw_aes_keyring() .key_name(key_name) .key_namespace(key_namespace) .wrapping_key(aws_smithy_types::Blob::new(AESWrappingKey)) .wrapping_alg(AesWrappingAlg::AlgAes256GcmIv12Tag16) .send() .await?;
Go
import ( mpl "aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygenerated" mpltypes "aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygeneratedtypes" client "github.com/aws/aws-encryption-sdk/awscryptographyencryptionsdksmithygenerated" esdktypes "github.com/aws/aws-encryption-sdk/awscryptographyencryptionsdksmithygeneratedtypes" ) //Instantiate the AWS Encryption SDK client. encryptionClient, err := client.NewClient(esdktypes.AwsEncryptionSdkConfig{}) if err != nil { panic(err) } // Define the key namespace and key name var keyNamespace = "A managed aes keys" var keyName = "My 256-bit AES wrapping key" // Optional: Create an encryption context encryptionContext := map[string]string{ "encryption": "context", "is not": "secret", "but adds": "useful metadata", "that can help you": "be confident that", "the data you are handling": "is what you think it is", } // Instantiate the material providers library matProv, err := mpl.NewClient(mpltypes.MaterialProvidersConfig{}) if err != nil { panic(err) } // Create Raw AES keyring aesKeyRingInput := mpltypes.CreateRawAesKeyringInput{ KeyName: keyName, KeyNamespace: keyNamespace, WrappingKey: aesWrappingKey, WrappingAlg: mpltypes.AesWrappingAlgAlgAes256GcmIv12Tag16, } aesKeyring, err := matProv.CreateRawAesKeyring(context.Background(), aesKeyRingInput) if err != nil { panic(err) }