

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

# 步骤 3：加密密钥材料
<a name="importing-keys-encrypt-key-material"></a>

[下载公有密钥和导入令牌](importing-keys-get-public-key-and-token.md)后，使用您下载的公有密钥和指定的包装算法对密钥材料进行加密。如果您需要替换公有密钥或导入令牌，或者更改包装算法，则必须下载新的公有密钥和导入令牌。有关 Amazon KMS 支持的公钥和封装算法的信息，请参阅[选择包装公有密钥规范](importing-keys-get-public-key-and-token.md#select-wrapping-key-spec)和[选择包装算法](importing-keys-get-public-key-and-token.md#select-wrapping-algorithm)。

密钥材料必须采用二进制格式。有关详细信息，请参阅 [导入密钥材料的要求](importing-keys-conceptual.md#importing-keys-material-requirements)。

**注意**  
对于非对称密钥对，仅加密和导入私钥。 Amazon KMS 从私钥派生公钥。  
不支持以下组合：ECC\$1NIST\$1P521 密钥材料、RSA\$12048 公有包装密钥规范和 RSAES\$1OAEP\$1SHA\$1\$1 包装算法。  
您不能使用 RSA\$12048 公有包装密钥直接包装 ECC\$1NIST\$1P521 密钥材料。使用更大的包装密钥或 RSA\$1AES\$1KEY\$1WRAP\$1SHA\$1\$1 包装算法。  
中国区域不支持 RSA\$1AES\$1KEY\$1WRAP\$1SHA\$1256 和 RSA\$1AES\$1KEY\$1WRAP\$1SHA\$11 包装算法。

通常，您可以在将密钥材料从硬件安全模块 (HSM) 或密钥管理系统导出时对其进行加密。有关如何以二进制格式导出密钥材料的信息，请参阅有关 HSM 或密钥管理系统的文档。您还可以参阅以下部分，该部分使用 OpenSSL 提供了概念验证演示。

加密密钥材料时，请使用与您在[下载公有密钥和导入令牌](importing-keys-get-public-key-and-token.md)时指定的相同的包装算法。要查找您指定的包装算法，请参阅关联[GetParametersForImport](https://docs.amazonaws.cn/kms/latest/APIReference/API_GetParametersForImport.html)请求的 CloudTrail 日志事件。

## 生成用于测试的密钥材料
<a name="importing-keys-example-key-material"></a>

以下 OpenSSL 命令生成每种支持类型的密钥材料以供测试。这些示例仅用于测试和 proof-of-concept演示。对于生产系统，请使用更安全的方法来生成您的密钥材料，例如硬件安全模块或密钥管理系统。

要将非对称密钥对的私有密钥转换为 DER 编码格式，请将密钥材料生成命令传送到以下 `openssl pkcs8` 命令。`topk8` 参数指示 OpenSSL 将私有密钥作为输入并返回 PKCS\$18 格式的密钥。（默认行为恰恰相反。） 

```
openssl pkcs8 -topk8 -outform der -nocrypt
```

以下命令为每种支持的密钥类型生成测试密钥材料。
+ 对称加密密钥（32 字节）

  此命令生成 256 位的对称密钥（32 字节的随机字符串）并将其保存在 `PlaintextKeyMaterial.bin` 文件中。您无需对这些密钥材料进行编码。

  ```
  openssl rand -out PlaintextKeyMaterial.bin 32
  ```

  仅在中国区域，您必须生成 128 位的对称密钥（16 字节的随机字符串）。

  ```
  openssl rand -out PlaintextKeyMaterial.bin 16
  ```
+ HMAC 密钥

  此命令生成指定大小的随机字节字符串。您无需对这些密钥材料进行编码。

  您的 HMAC 密钥的长度必须与 KMS 密钥的密钥规范定义的长度相匹配。例如，如果 KMS 密钥为 HMAC\$1384，则必须导入 384 位（48 字节）的密钥。

  ```
  openssl rand -out HMAC_224_PlaintextKey.bin 28
  
  openssl rand -out HMAC_256_PlaintextKey.bin 32
  
  openssl rand -out HMAC_384_PlaintextKey.bin 48
  
  openssl rand -out HMAC_512_PlaintextKey.bin 64
  ```
+ RSA 私有密钥

  ```
  openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 | openssl pkcs8 -topk8 -outform der -nocrypt > RSA_2048_PrivateKey.der
  
  openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:3072 | openssl pkcs8 -topk8 -outform der -nocrypt > RSA_3072_PrivateKey.der
  
  openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:4096 | openssl pkcs8 -topk8 -outform der -nocrypt > RSA_4096_PrivateKey.der
  ```
+ ECC 私有密钥

  ```
  openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 | openssl pkcs8 -topk8 -outform der -nocrypt > ECC_NIST_P256_PrivateKey.der
  
  openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-384 | openssl pkcs8 -topk8 -outform der -nocrypt > ECC_NIST_P384_PrivateKey.der
  
  openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-521 | openssl pkcs8 -topk8 -outform der -nocrypt > ECC_NIST_P521_PrivateKey.der
  
  openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:secp256k1 | openssl pkcs8 -topk8 -outform der -nocrypt > ECC_SECG_P256K1_PrivateKey.der
  ```
+ SM2 私钥（仅限中国地区）

  ```
  openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:sm2 | openssl pkcs8 -topk8 -outform der -nocrypt > SM2_PrivateKey.der
  ```

## 使用 OpenSSL 加密密钥材料的示例
<a name="importing-keys-encrypt-key-material-openssl"></a>

以下示例说明如何使用 [OpenSSL](https://openssl.org/) 通过您下载的公有密钥对密钥材料进行加密。要使用 SM2 公钥加密密钥材料（仅限中国地区），请使用[`SM2OfflineOperationHelper`该](offline-operations.md#key-spec-sm-offline-helper)类。有关每种包装算法支持的密钥材料类型的更多信息，请参阅 [选择包装算法](importing-keys-get-public-key-and-token.md#select-wrapping-algorithm)。

**重要**  
这些示例仅为概念验证演示。对于生产系统，请使用更安全的方法 (如商业 HSM 或密钥管理系统) 来生成和存储您的密钥材料。  
不支持以下组合：ECC\$1NIST\$1P521 密钥材料、RSA\$12048 公有包装密钥规范和 RSAES\$1OAEP\$1SHA\$1\$1 包装算法。  
您不能使用 RSA\$12048 公有包装密钥直接包装 ECC\$1NIST\$1P521 密钥材料。使用更大的包装密钥或 RSA\$1AES\$1KEY\$1WRAP\$1SHA\$1\$1 包装算法。

------
#### [ RSAES\$1OAEP\$1SHA\$11 ]

Amazon KMS 支持对称加密密钥 (SYMMETRIC\$1DEFAULT)、椭圆曲线 (ECC) 私钥、私钥和 HMAC 密钥的 RSAES\$1OAEP\$1SHA\$11。 SM2 

RSAES\$1OAEP\$1SHA\$11 不支持 RSA 私有密钥。此外，您不能使用采用任何 RSAES\$1OAEP\$1SHA\$1\$1 包装算法的 RSA\$12048 公有包装密钥来包装 ECC\$1NIST\$1P521（secp521r1）私有密钥。您必须使用更大的公有包装密钥或 RSA\$1AES\$1KEY\$1WRAP 包装算法。

以下示例使用[您下载的公有密钥](importing-keys-get-public-key-and-token.md)和 RSAES\$1OAEP\$1SHA\$11 包装算法对密钥材料进行加密，并将其保存在 `EncryptedKeyMaterial.bin` 文件中。

在本示例中：
+ *`WrappingPublicKey.bin`* 是包含下载的包装公有密钥的文件。
+ *`PlaintextKeyMaterial.bin`* 是包含您正在加密的密钥材料的文件，例如 `PlaintextKeyMaterial.bin`、`HMAC_384_PlaintextKey.bin` 或 `ECC_NIST_P521_PrivateKey.der`。

```
$ openssl pkeyutl \
    -encrypt \
    -in PlaintextKeyMaterial.bin \
    -out EncryptedKeyMaterial.bin \
    -inkey WrappingPublicKey.bin \
    -keyform DER \
    -pubin \
    -pkeyopt rsa_padding_mode:oaep \
    -pkeyopt rsa_oaep_md:sha1
```

------
#### [ RSAES\$1OAEP\$1SHA\$1256 ]

Amazon KMS 支持对称加密密钥 (SYMMETRIC\$1DEFAULT)、椭圆曲线 (ECC) 私钥、私钥和 HMAC 密钥的 RSAES\$1OAEP\$1SHA\$1256。 SM2 

RSAES\$1OAEP\$1SHA\$1256 不支持 RSA 私有密钥。此外，您不能使用采用任何 RSAES\$1OAEP\$1SHA\$1\$1 包装算法的 RSA\$12048 公有包装密钥来包装 ECC\$1NIST\$1P521（secp521r1）私有密钥。您必须使用更大的公有密钥或 RSA\$1AES\$1KEY\$1WRAP 包装算法。

以下示例使用[您下载的公有密钥](importing-keys-get-public-key-and-token.md)和 RSAES\$1OAEP\$1SHA\$1256 包装算法对密钥材料进行加密，并将其保存在 `EncryptedKeyMaterial.bin` 文件中。

在本示例中：
+ *`WrappingPublicKey.bin`* 是包含已下载的公有包装密钥的文件。如果您是从控制台下载的公有密钥，则此文件的名称为 `wrappingKey_KMS key_key_ID_timestamp`（例如，`wrappingKey_f44c4e20-f83c-48f4-adc6-a1ef38829760_0809092909`）。
+ *`PlaintextKeyMaterial.bin`* 是包含您正在加密的密钥材料的文件，例如 `PlaintextKeyMaterial.bin`、`HMAC_384_PlaintextKey.bin` 或 `ECC_NIST_P521_PrivateKey.der`。

```
$ openssl pkeyutl \
    -encrypt \
    -in PlaintextKeyMaterial.bin \
    -out EncryptedKeyMaterial.bin \
    -inkey WrappingPublicKey.bin \
    -keyform DER \
    -pubin \
    -pkeyopt rsa_padding_mode:oaep \
    -pkeyopt rsa_oaep_md:sha256 \
    -pkeyopt rsa_mgf1_md:sha256
```

------
#### [ RSA\$1AES\$1KEY\$1WRAP\$1SHA\$11 ]

RSA\$1AES\$1KEY\$1WRAP\$1SHA\$11 包装算法涉及两个加密操作。

1. 使用您生成的 AES 对称密钥和 AES 对称加密算法对密钥材料进行加密。

1. 使用您下载的公有密钥和 RSAES\$1OAEP\$1SHA\$11 包装算法加密您使用的 AES 对称密钥。

RSA\$1AES\$1KEY\$1WRAP\$1SHA\$11 包装算法需要 OpenSSL 版本 3.*x* 或更高版本。

1. 

**生成 256 位 AES 对称加密密钥**

   此命令生成由 256 个随机位组成的 AES 对称加密密钥，并将其保存在 `aes-key.bin` 文件中

   ```
   # Generate a 32-byte AES symmetric encryption key
   $ openssl rand -out aes-key.bin 32
   ```

1. 

**使用 AES 对称加密密钥加密您的密钥材料**

   此命令使用 AES 对称加密密钥对您的密钥材料进行加密，并将加密的密钥材料保存在 `key-material-wrapped.bin` 文件中。

   在此示例命令中：
   + *`PlaintextKeyMaterial.bin`* 是包含您要导入的密钥材料的文件，例如 `PlaintextKeyMaterial.bin`、`HMAC_384_PlaintextKey.bin`、`RSA_3072_PrivateKey.der` 或 `ECC_NIST_P521_PrivateKey.der`。
   + *`aes-key.bin`* 是包含您在上一个命令中生成的 256 位 AES 对称加密密钥的文件。

   ```
   # Encrypt your key material with the AES symmetric encryption key
   $ openssl enc -id-aes256-wrap-pad \
           -K "$(xxd -p < aes-key.bin | tr -d '\n')" \
           -iv A65959A6 \
           -in PlaintextKeyMaterial.bin \
           -out key-material-wrapped.bin
   ```

1. 

**使用公有密钥加密您的 AES 对称加密密钥**

   此命令使用您下载的公有密钥和 RSAES\$1OAEP\$1SHA\$11 包装算法对您的 AES 对称加密密钥进行加密，对其进行 DER 编码，然后将其保存在 `aes-key-wrapped.bin` 文件中。

   在此示例命令中：
   + *`WrappingPublicKey.bin`* 是包含已下载的公有包装密钥的文件。如果您是从控制台下载的公有密钥，则此文件的名称为 `wrappingKey_KMS key_key_ID_timestamp`（例如，`wrappingKey_f44c4e20-f83c-48f4-adc6-a1ef38829760_0809092909`
   + *`aes-key.bin`* 是包含您在本示例序列的第一个命令中生成的 256 位 AES 对称加密密钥的文件。

   ```
   # Encrypt your AES symmetric encryption key with the downloaded public key
   $ openssl pkeyutl \
       -encrypt \
       -in aes-key.bin \
       -out aes-key-wrapped.bin \
       -inkey WrappingPublicKey.bin \
       -keyform DER \
       -pubin \
       -pkeyopt rsa_padding_mode:oaep \
       -pkeyopt rsa_oaep_md:sha1 \
       -pkeyopt rsa_mgf1_md:sha1
   ```

1. 

**生成要导入的文件**

   将文件与加密的密钥材料连接起来，并将文件与加密的 AES 密钥连接起来。将它们保存在 `EncryptedKeyMaterial.bin` 文件中，也就是您要在 [步骤 4：导入密钥材料](importing-keys-import-key-material.md) 中导入的文件。

   在此示例命令中：
   + *`key-material-wrapped.bin`* 是包含您的已加密密钥材料的文件。
   + *`aes-key-wrapped.bin`* 是包含已加密 AES 加密密钥的文件。

   ```
   # Combine the encrypted AES key and encrypted key material in a file
   $ cat aes-key-wrapped.bin key-material-wrapped.bin > EncryptedKeyMaterial.bin
   ```

------
#### [ RSA\$1AES\$1KEY\$1WRAP\$1SHA\$1256 ]

RSA\$1AES\$1KEY\$1WRAP\$1SHA\$1256 包装算法涉及两个加密操作。

1. 使用您生成的 AES 对称密钥和 AES 对称加密算法对密钥材料进行加密。

1. 使用您下载的公有密钥和 RSAES\$1OAEP\$1SHA\$1256 包装算法加密您使用的 AES 对称密钥。

RSA\$1AES\$1KEY\$1WRAP\$1SHA\$1256 包装算法需要 OpenSSL 版本 3.*x* 或更高版本。

1. 

**生成 256 位 AES 对称加密密钥**

   此命令生成由 256 个随机位组成的 AES 对称加密密钥，并将其保存在 `aes-key.bin` 文件中

   ```
   # Generate a 32-byte AES symmetric encryption key
   $ openssl rand -out aes-key.bin 32
   ```

1. 

**使用 AES 对称加密密钥加密您的密钥材料**

   此命令使用 AES 对称加密密钥对您的密钥材料进行加密，并将加密的密钥材料保存在 `key-material-wrapped.bin` 文件中。

   在此示例命令中：
   + *`PlaintextKeyMaterial.bin`* 是包含您要导入的密钥材料的文件，例如 `PlaintextKeyMaterial.bin`、`HMAC_384_PlaintextKey.bin`、`RSA_3072_PrivateKey.der` 或 `ECC_NIST_P521_PrivateKey.der`。
   + *`aes-key.bin`* 是包含您在上一个命令中生成的 256 位 AES 对称加密密钥的文件。

   ```
   # Encrypt your key material with the AES symmetric encryption key
   $ openssl enc -id-aes256-wrap-pad \
           -K "$(xxd -p < aes-key.bin | tr -d '\n')" \
           -iv A65959A6 \
           -in PlaintextKeyMaterial.bin \
           -out key-material-wrapped.bin
   ```

1. 

**使用公有密钥加密您的 AES 对称加密密钥**

   此命令使用您下载的公有密钥和 RSAES\$1OAEP\$1SHA\$1256 包装算法对您的 AES 对称加密密钥进行加密，对其进行 DER 编码，然后将其保存在 `aes-key-wrapped.bin` 文件中。

   在此示例命令中：
   + *`WrappingPublicKey.bin`* 是包含已下载的公有包装密钥的文件。如果您是从控制台下载的公有密钥，则此文件的名称为 `wrappingKey_KMS key_key_ID_timestamp`（例如，`wrappingKey_f44c4e20-f83c-48f4-adc6-a1ef38829760_0809092909`
   + *`aes-key.bin`* 是包含您在本示例序列的第一个命令中生成的 256 位 AES 对称加密密钥的文件。

   ```
   # Encrypt your AES symmetric encryption key with the downloaded public key
   $ openssl pkeyutl \
       -encrypt \
       -in aes-key.bin \
       -out aes-key-wrapped.bin \
       -inkey WrappingPublicKey.bin \
       -keyform DER \
       -pubin \
       -pkeyopt rsa_padding_mode:oaep \
       -pkeyopt rsa_oaep_md:sha256 \
       -pkeyopt rsa_mgf1_md:sha256
   ```

1. 

**生成要导入的文件**

   将文件与加密的密钥材料连接起来，并将文件与加密的 AES 密钥连接起来。将它们保存在 `EncryptedKeyMaterial.bin` 文件中，也就是您要在 [步骤 4：导入密钥材料](importing-keys-import-key-material.md) 中导入的文件。

   在此示例命令中：
   + *`key-material-wrapped.bin`* 是包含您的已加密密钥材料的文件。
   + *`aes-key-wrapped.bin`* 是包含已加密 AES 加密密钥的文件。

   ```
   # Combine the encrypted AES key and encrypted key material in a file
   $ cat aes-key-wrapped.bin key-material-wrapped.bin > EncryptedKeyMaterial.bin
   ```

------

继续执行[步骤 4：导入密钥材料](importing-keys-import-key-material.md)。