

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

# 原始 AES 密钥环
<a name="use-raw-aes-keyring"></a>

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

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

当 AES 加密密钥与 AES 加密密钥一起使用 AWS Encryption SDK for Python 时，Raw AES 密钥环等同于 AWS Encryption SDK for Java 和中的[RawMasterKey](https://aws-encryption-sdk-python.readthedocs.io/en/latest/generated/aws_encryption_sdk.key_providers.raw.html#aws_encryption_sdk.key_providers.raw.RawMasterKey)类并与该类互操作。[JceMasterKey](https://aws.github.io/aws-encryption-sdk-java/com/amazonaws/encryptionsdk/jce/JceMasterKey.html)您可以使用一种实现加密数据，用使用相同包装密钥的任何其他实现进行解密。有关更多信息，请参阅 [密钥环兼容性](choose-keyring.md#keyring-compatibility)。

**密钥命名空间和名称**

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

**注意**  
密钥命名空间和密钥名称等同于 `JceMasterKey` 和 `RawMasterKey` 中*提供程序 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](https://github.com/aws/aws-encryption-sdk-c/blob/master/examples/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](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/Examples/Keyring/RawAESKeyringExample.cs)。

以下示例使用版本 4。 *x* 及更高版本 AWS Encryption SDK 适用于.NET。

```
// 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](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API)在构造密钥环之前，必须使用`RawAesKeyringWebCrypto.importCryptoKey()`将原始密钥材料导入 WebCrypto 后端。这样可以确保即使对的所有调用都是异步的，密钥环也是完整 WebCrypto 的。

然后，要实例化原始 AES 密钥环，请使用 `RawAesKeyringWebCrypto()` 方法。您必须根据密钥材料的长度指定 AES 包装算法（“包装套件”）。有关完整的示例，请参阅 [aes\_simple.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/example-browser/src/aes_simple.ts)（浏览器）。JavaScript 

以下示例使用`buildClient`函数来指定[默认的承诺策略](migrate-commitment-policy.md)`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`。您也可以使用`buildClient`来限制加密消息中加密数据密钥的数量。有关更多信息，请参阅 [限制加密数据密钥](configure.md#config-limit-keys)。

```
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](https://github.com/aws/aws-encryption-sdk-javascript//blob/master/modules/example-node/src/aes_simple.ts) (Node.js)。JavaScript 

以下示例使用`buildClient`函数来指定[默认的承诺策略](migrate-commitment-policy.md)`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`。您也可以使用`buildClient`来限制加密消息中加密数据密钥的数量。有关更多信息，请参阅 [限制加密数据密钥](configure.md#config-limit-keys)。

```
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 ]

以下示例使用[默认承诺策略](migrate-commitment-policy.md)实例化 AWS Encryption SDK 客户端。`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`有关完整示例，请参阅中 AWS Encryption SDK for Python 存储库中的 [raw\_aes\_keyring\_example.py](https://github.com/aws/aws-encryption-sdk-python/tree/master/examples/src/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)
}
```

------