

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

# 更新 AWS KMS 主密钥提供程序
<a name="migrate-mkps-v2"></a>

要迁移到最新版本 1. *x* 版本的 AWS Encryption SDK，然后是 2.0 版。 *x* 或更高版本，您必须将传统 AWS KMS 的主密钥提供程序替换为在[*严格模式或*发现模式*下*](about-versions.md#changes-to-mkps)显式创建的主密钥提供程序。旧版主密钥提供程序在版本 1.7.*x* 中弃用并在版本 2.0.*x* 中移除。使用 [AWS Encryption SDK for Java](java.md)、[AWS Encryption SDK for Python](python.md) 和 [AWS Encryption CLI](crypto-cli.md) 的应用程序和脚本需要进行此项更改。本节中的示例将演示如何更新代码。

**注意**  
在 Python 中，[打开弃用警告](https://docs.python.org/3/library/warnings.html)。这将帮助您识别代码中需要更新的部分。

如果您使用的是 AWS KMS 主密钥（不是主密钥提供程序），则可以跳过此步骤。 AWS KMS 主密钥不会被弃用或删除。这些密钥仅使用您指定的包装密钥进行加密和解密。

本节中的示例重点介绍需要更改的代码元素。有关更新后的代码的完整示例，请参阅您的[编程语言 GitHub](programming-languages.md)存储库的 “示例” 部分。此外，这些示例通常使用 key ARNs 来表示 AWS KMS keys。在创建用于加密的主密钥提供程序时，可以使用任何有效的 AWS KMS [密钥标识符](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id)来表示。 AWS KMS key 如果创建用于解密的主密钥提供程序，必须使用密钥 ARN。

**了解有关迁移的更多信息**

对于所有 AWS Encryption SDK 用户，请在中了解如何设置您的承诺政策[设置您的承诺策略](migrate-commitment-policy.md)。

对于 AWS Encryption SDK for C 和 AWS Encryption SDK for JavaScript 用户，请在中[更新 AWS KMS 钥匙圈](migrate-keyrings-v2.md)了解钥匙圈的可选更新。

**Topics**
+ [迁移到严格模式](#migrate-mkp-strict-mode)
+ [迁移到发现模式](#migrate-mkp-discovery-mode)

## 迁移到严格模式
<a name="migrate-mkp-strict-mode"></a>

更新到最新版本后 1. *x* 版本的 AWS Encryption SDK，在严格模式下，用主密钥提供程序替换旧版主密钥提供程序。在严格模式下，必须指定加密和解密时要使用的包装密钥。仅 AWS Encryption SDK 使用您指定的包装密钥。已弃用的主密钥提供程序可以使用任何加密数据密钥的提供程序 AWS KMS key 来解密数据，包括在不同的 AWS KMS keys AWS 账户 地区和区域。

1.7 AWS Encryption SDK 版本中引入了严格模式的主密钥提供程序。 *x*。这些主密钥提供程序取代旧版主密钥提供程序，其在 1.7.*x* 中弃用并在 2.0.*x* 中移除。在严格模式下使用主密钥提供程序是一种 AWS Encryption SDK [最佳实践](best-practices.md)。

以下代码创建可用于加密和解密的严格模式下的主密钥提供程序。

------
#### [ Java ]

此示例表示使用版本 AWS Encryption SDK for Java 1.6.2 或更早版本的应用程序中的代码。

此代码使用该`KmsMasterKeyProvider.builder()`方法来实例化使用 AWS KMS 主密钥提供程序 AWS KMS key 作为包装密钥。

```
// Create a master key provider
// Replace the example key ARN with a valid one
String awsKmsKey = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab";

KmsMasterKeyProvider masterKeyProvider = KmsMasterKeyProvider.builder()
    .withKeysForEncryption(awsKmsKey)
    .build();
```

此示例表示使用 AWS Encryption SDK for Java 版本 1.7.*x* 或更高版本的应用程序中的代码。有关完整的示例，请参阅 [BasicEncryptionExample.java。](https://github.com/aws/aws-encryption-sdk-java/blob/master/src/examples/java/com/amazonaws/crypto/examples/v2/BasicEncryptionExample.java)

前面的示例使用的 `Builder.build()` 和 `Builder.withKeysForEncryption()` 方法在版本 1.7.*x* 中弃用并在版本 2.0.*x* 中移除。

为了更新为严格模式下的主密钥提供程序，此代码将对弃用方法的调用替换为对新 `Builder.buildStrict()` 方法的调用。此示例指定一个 AWS KMS key 作为包装密钥，但该`Builder.buildStrict()`方法可以采用多个列表 AWS KMS keys。

```
// Create a master key provider in strict mode
// Replace the example key ARN with a valid one from your AWS 账户.
String awsKmsKey = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab";

KmsMasterKeyProvider masterKeyProvider = KmsMasterKeyProvider.builder()
    .buildStrict(awsKmsKey);
```

------
#### [ Python ]

此示例表示使用 AWS Encryption SDK for Python版本 1.4.1 的应用程序中的代码。此代码使用 `KMSMasterKeyProvider`，其在版本 1.7.*x* 中弃用并在版本 2.0.*x* 中移除。解密时，它会使用任何加密数据密钥的密钥 AWS KMS key ，而不考虑 AWS KMS keys 您指定的密钥。

请注意，`KMSMasterKey` 并未弃用或移除。加密和解密时，它仅使用您指定的。 AWS KMS key 

```
# Create a master key provider
# Replace the example key ARN with a valid one
key_1 = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
key_2 = "arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321"

aws_kms_master_key_provider = KMSMasterKeyProvider(
   key_ids=[key_1, key_2]
)
```

此示例表示使用 AWS Encryption SDK for Python版本 1.7.*x* 的应用程序中的代码。有关完整示例，请参阅 [basic\$1encryption.py](https://github.com/aws/aws-encryption-sdk-python/blob/master/examples/src/legacy/basic_encryption.py)。

为了更新为严格模式下的主密钥提供程序，此代码将对 `KMSMasterKeyProvider()` 的调用替换为对 `StrictAwsKmsMasterKeyProvider()` 的调用。

```
# Create a master key provider in strict mode
# Replace the example key ARNs with valid values from your AWS 账户
key_1 = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"
key_2 = "arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321"

aws_kms_master_key_provider = StrictAwsKmsMasterKeyProvider(
    key_ids=[key_1, key_2]
)
```

------
#### [ AWS Encryption CLI ]

此示例说明如何使用加密 AWS CLI 版本 1.1.7 或更早版本进行加密和解密。

在版本 1.1.7 及更早版本中，加密时，您可以在指定一个或多个主密钥（或*包装密钥*），例如 AWS KMS key。解密时，除非您使用的是自定义主密钥提供程序，否则无法指定任何包装密钥。 AWS 加密 CLI 可以使用任何对数据密钥进行加密的包装密钥。

```
\\ Replace the example key ARN with a valid one
$ keyArn=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab

\\ Encrypt your plaintext data
$ aws-encryption-cli --encrypt \
                     --input hello.txt \
                     --master-keys key=$keyArn \
                     --metadata-output ~/metadata \
                     --encryption-context purpose=test \
                     --output .

\\ Decrypt your ciphertext               
$ aws-encryption-cli --decrypt \
                     --input hello.txt.encrypted \
                     --encryption-context purpose=test \
                     --metadata-output ~/metadata \
                     --output .
```

此示例说明如何使用加密 AWS CLI 版本 1.7 进行加密和解密。 *x* 或更高版本。有关完整示例，请参阅 [AWS 加密 CLI 的示例](crypto-cli-examples.md)。

`--master-keys` 参数在版本 1.7.*x* 中弃用并在版本 2.0.*x* 中移除。该参数由加密和解密命令所需的 `--wrapping-keys` 参数取代。该参数支持严格模式和发现模式。严格模式是一种 AWS Encryption SDK 最佳实践，可确保您使用所需的包装密钥。

要升级到*严格模式*，请在加密和解密时使用 `--wrapping-keys` 参数的**密钥**属性指定包装密钥。

```
\\ Replace the example key ARN with a valid value
$ keyArn=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab

\\ Encrypt your plaintext data
$ aws-encryption-cli --encrypt \
                     --input hello.txt \
                     --wrapping-keys key=$keyArn \
                     --metadata-output ~/metadata \
                     --encryption-context purpose=test \
                     --output .

\\ Decrypt your ciphertext               
$ aws-encryption-cli --decrypt \
                     --input hello.txt.encrypted \
                     --wrapping-keys key=$keyArn \
                     --encryption-context purpose=test \
                     --metadata-output ~/metadata \
                     --output .
```

------

## 迁移到发现模式
<a name="migrate-mkp-discovery-mode"></a>

从 1.7 版本开始。 *x*， AWS Encryption SDK [最佳做法](best-practices.md)是对 AWS KMS 主密钥提供者使用*严格模式*，也就是说，在加密和解密时指定包装密钥。加密时必须始终指定包装密钥。但是在某些情况下，指定用于解密 ARNs 的 AWS KMS keys 密钥是不切实际的。例如，如果您在加密 AWS KMS keys 时使用别名进行识别，那么如果在解密时必须列出密钥 ARNs ，则会失去别名的好处。此外，由于发现模式下的主密钥提供程序的行为类似于原始主密钥提供程序，因此您可以暂时将其用作迁移策略的一部分，然后升级到严格模式下的主密钥提供程序。

在这种情况下，您可以在*发现模式*下使用主密钥提供程序。这些主密钥提供程序不允许您指定包装密钥，因此您不能用其进行加密。在解密时，这些提供程序可以任何使用加密数据密钥的包装密钥。但是，与行为方式相同的旧版主密钥提供程序不同，您可以在发现模式下明确创建。在发现模式下使用主密钥提供程序时，您可以将可以使用的包装密钥限制为特定 AWS 账户。此发现筛选条件为可选项，但却是我们建议的最佳实践。有关 AWS 分区和账户的信息，请参阅《AWS 一般参考》** 中的 [Amazon 资源名称](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arns-syntax)。

以下示例在严格模式下创建用于加密 AWS KMS 的主密钥提供程序和在发现模式下创建用于解密 AWS KMS 的主密钥提供程序。发现模式下的主密钥提供程序使用发现筛选条件将用于解密的包装密钥限制在 `aws` 分区和特定示例 AWS 账户的密钥。尽管这一简易示例没有必要使用账户筛选条件，但是当一个应用程序加密数据而另一个应用程序解密数据时，这是一种非常有益的最佳实践。

------
#### [ Java ]

此示例表示使用 AWS Encryption SDK for Java版本 1.7.*x* 或更高版本的应用程序中的代码。有关完整的示例，请参阅 [DiscoveryDecryptionExample.java。](https://github.com/aws/aws-encryption-sdk-java/blob/master/src/examples/java/com/amazonaws/crypto/examples/)

为了实例化用于加密的严格模式下的主密钥提供程序，此示例使用 `Builder.buildStrict()` 方法。为了实例化用于解密的发现模式下的主密钥提供程序，此示例使用 `Builder.buildDiscovery()` 方法。该`Builder.buildDiscovery()`方法采用`DiscoveryFilter`，将限制 AWS Encryption SDK AWS KMS keys 为指定 AWS 分区和帐户。

```
// Create a master key provider in strict mode for encrypting
// Replace the example alias ARN with a valid one from your AWS 账户.
String awsKmsKey = "arn:aws:kms:us-west-2:111122223333:alias/ExampleAlias";

KmsMasterKeyProvider encryptingKeyProvider = KmsMasterKeyProvider.builder()
    .buildStrict(awsKmsKey);

// Create a master key provider in discovery mode for decrypting
// Replace the example account IDs with valid values.
DiscoveryFilter accounts = new DiscoveryFilter("aws", Arrays.asList("111122223333", "444455556666"));

KmsMasterKeyProvider decryptingKeyProvider = KmsMasterKeyProvider.builder()
    .buildDiscovery(accounts);
```

------
#### [ Python ]

 此示例表示使用 AWS Encryption SDK for Python 版本 1.7.*x* 或更高版本的应用程序中的代码。有关完整示例，请参阅 [discovery\$1kms\$1provider.py](https://github.com/aws/aws-encryption-sdk-python/blob/master/examples/src/legacy/discovery_kms_provider.py)。

为了在创建用于加密的严格模式下的主密钥提供程序，此示例使用 `StrictAwsKmsMasterKeyProvider`。要在发现模式下创建用于解密的主密钥提供程序，`DiscoveryFilter`该提供程序 AWS Encryption SDK 将`DiscoveryAwsKmsMasterKeyProvider`与限制 AWS KMS keys 在指定的 AWS 分区和帐户中。

```
# Create a master key provider in strict mode
# Replace the example key ARN and alias ARNs with valid values from your AWS 账户.
key_1 = "arn:aws:kms:us-west-2:111122223333:alias/ExampleAlias"
key_2 = "arn:aws:kms:us-west-2:444455556666:key/1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d"

aws_kms_master_key_provider = StrictAwsKmsMasterKeyProvider(
    key_ids=[key_1, key_2]
)

# Create a master key provider in discovery mode for decrypting
# Replace the example account IDs with valid values
accounts = DiscoveryFilter(
    partition="aws",
    account_ids=["111122223333", "444455556666"]
)
aws_kms_master_key_provider = DiscoveryAwsKmsMasterKeyProvider(
        discovery_filter=accounts
)
```

------
#### [ AWS Encryption CLI ]

此示例说明如何使用加密 AWS CLI 版本 1.7 进行加密和解密。 *x* 或更高版本。从版本 1.7.*x* 开始，加密和解密时需要使用 `--wrapping-keys` 参数。`--wrapping-keys` 参数支持严格模式和发现模式。有关完整示例，请参阅 [AWS 加密 CLI 的示例](crypto-cli-examples.md)。

加密时，此示例指定包装密钥，这是必需的。解密时，此示例使用值为 `true` 的 `--wrapping-keys` 参数的 `discovery` 属性明确选择*发现模式*。

为了将 AWS Encryption SDK 可以在发现模式下使用的包装密钥限制为特定的封装密钥 AWS 账户，此示例使用了`--wrapping-keys`参数的`discovery-partition`和`discovery-account`属性。这些可选属性仅在 `discovery` 属性设置为 `true` 时有效。必须同时使用 `discovery-partition` 和 `discovery-account` 属性；单独使用则无效。

```
\\ Replace the example key ARN with a valid value
$ keyAlias=arn:aws:kms:us-west-2:111122223333:alias/ExampleAlias

\\ Encrypt your plaintext data
$ aws-encryption-cli --encrypt \
                     --input hello.txt \
                     --wrapping-keys key=$keyAlias \
                     --metadata-output ~/metadata \
                     --encryption-context purpose=test \
                     --output .

\\ Decrypt your ciphertext
\\ Replace the example account IDs with valid values           
$ aws-encryption-cli --decrypt \
                     --input hello.txt.encrypted \
                     --wrapping-keys discovery=true \
                                     discovery-partition=aws \
                                     discovery-account=111122223333 \
                                     discovery-account=444455556666 \
                     --encryption-context purpose=test \
                     --metadata-output ~/metadata \
                     --output .
```

------