

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# AWS KMS ECDH keyring
<a name="use-kms-ecdh-keyring"></a>

 AWS KMS ECDH keyring 使用非對稱金鑰協議[AWS KMS keys](https://docs.aws.amazon.com/kms/latest/developerguide/key-types.html)，在雙方之間衍生共用對稱包裝金鑰。首先， keyring 使用橢圓曲線 Diffie-Hellman (ECDH) 金鑰協議演算法，從寄件者的 KMS 金鑰對和收件人的公有金鑰中的私有金鑰衍生共用秘密。然後， keyring 會使用共用秘密來衍生保護資料加密金鑰的共用包裝金鑰。 AWS Encryption SDK 用來衍生共用包裝金鑰的金鑰衍生函數 (`KDF_CTR_HMAC_SHA384`) 符合[金鑰衍生的 NIST 建議](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-108r1-upd1.pdf)。

金鑰衍生函數會傳回 64 個位元組的金鑰材料。為了確保雙方都使用正確的金鑰材料， AWS Encryption SDK 使用前 32 個位元組做為承諾金鑰，最後 32 個位元組做為共用包裝金鑰。在解密時，如果 keyring 無法重現存放在訊息標頭加密文字上的相同承諾金鑰和共用包裝金鑰，則操作會失敗。例如，如果您使用使用 **Alice** 私有金鑰和 **Bob **公有金鑰設定的 keyring 加密資料，則使用 **Bob **私有金鑰和 **Alice 公**有金鑰設定的 keyring 將重現相同的承諾金鑰和共用包裝金鑰，並能夠解密資料。如果 Bob 的公有金鑰不是來自 KMS 金鑰對，則 Bob 可以建立[原始 ECDH keyring](use-raw-ecdh-keyring.md) 來解密資料。

 AWS KMS ECDH keyring 使用 AES-GCM 使用對稱金鑰加密資料。然後，資料金鑰會使用 AES-GCM 使用衍生的共用包裝金鑰進行信封加密。每個 AWS KMS ECDH keyring 只能有一個共用包裝金鑰，但您可以在多 keyring 中單獨包含多個 AWS KMS ECDH keyring 或與其他 [keyring ](use-multi-keyring.md)一起包含。

**程式設計語言相容性**  
 AWS KMS ECDH keyring 會在 [Cryptographic Material Providers Library](https://github.com/aws/aws-cryptographic-material-providers-library) (MPL) 的 1.5.0 版中推出，並受下列程式設計語言和版本支援：
+ 3.*x* 版 適用於 JAVA 的 AWS Encryption SDK
+  AWS Encryption SDK 適用於 .NET 的 4.*x* 版和更新版本
+ 4.*x* 版 適用於 Python 的 AWS Encryption SDK，與選用的 MPL 相依性搭配使用時。
+ for Rust 的 1.*x* AWS Encryption SDK 版
+ 適用於 Go 的 0.1.*x* AWS Encryption SDK 版或更新版本

**Topics**
+ [AWS KMS ECDH keyrings 的必要許可](#kms-ecdh-permissions)
+ [建立 AWS KMS ECDH keyring](#kms-ecdh-create)
+ [建立 AWS KMS ECDH 探索 keyring](#kms-ecdh-discovery)

## AWS KMS ECDH keyrings 的必要許可
<a name="kms-ecdh-permissions"></a>

 AWS Encryption SDK 不需要 AWS 帳戶，也不依賴任何 AWS 服務。不過，若要使用 AWS KMS ECDH keyring，您需要 AWS 帳戶和 keyring AWS KMS keys 中 的下列最低許可。許可會根據您使用的金鑰協議結構描述而有所不同。
+ 若要使用`KmsPrivateKeyToStaticPublicKey`金鑰協議結構描述來加密和解密資料，您需要*寄件者*非對稱 KMS 金鑰對上的 [kms:GetPublicKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GetPublicKey.html) 和 [kms:DeriveSharedSecret](https://docs.aws.amazon.com/kms/latest/APIReference/API_DeriveSharedSecret.html)。如果您在執行個體化 keyring 時直接提供寄件者的 DER 編碼公有金鑰，則只需要寄件者的非對稱 KMS 金鑰對上的 [kms:DeriveSharedSecret](https://docs.aws.amazon.com/kms/latest/APIReference/API_DeriveSharedSecret.html) 許可。
+ 若要使用`KmsPublicKeyDiscovery`金鑰協議結構描述解密資料，您需要指定非對稱 KMS 金鑰對上的 [kms:DeriveSharedSecret](https://docs.aws.amazon.com/kms/latest/APIReference/API_DeriveSharedSecret.html) 和 [kms:GetPublicKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GetPublicKey.html) 許可。

## 建立 AWS KMS ECDH keyring
<a name="kms-ecdh-create"></a>

若要建立加密和解密資料的 AWS KMS ECDH keyring，您必須使用`KmsPrivateKeyToStaticPublicKey`金鑰協議結構描述。若要使用`KmsPrivateKeyToStaticPublicKey`金鑰協議結構描述初始化 AWS KMS ECDH keyring，請提供下列值：
+ **寄件者的 AWS KMS key ID**

  必須識別`KeyUsage`值為 的非對稱 NIST 建議的橢圓曲線 (ECC) KMS 金鑰對`KEY_AGREEMENT`。寄件者的私有金鑰用於衍生共用秘密。
+ **（選用） 寄件者的公有金鑰**

  必須是 DER 編碼的 X.509 公有金鑰，也稱為 `SubjectPublicKeyInfo`(SPKI)，如 [RFC 5280 ](https://tools.ietf.org/html/rfc5280)所定義。

   AWS KMS [GetPublicKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GetPublicKey.html) 操作會以所需的 DER 編碼格式傳回非對稱 KMS 金鑰對的公有金鑰。

  若要減少 keyring 進行的 AWS KMS 呼叫數量，您可以直接提供寄件者的公有金鑰。如果未為寄件者的公有金鑰提供值， keyring 會呼叫 AWS KMS 來擷取寄件者的公有金鑰。
+ **收件人的公有金鑰**

  您必須提供收件人的 DER 編碼 X.509 公有金鑰，也稱為 `SubjectPublicKeyInfo`(SPKI)，如 [RFC 5280 ](https://tools.ietf.org/html/rfc5280)所定義。

   AWS KMS [GetPublicKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GetPublicKey.html) 操作會以所需的 DER 編碼格式傳回非對稱 KMS 金鑰對的公有金鑰。
+ **曲線規格**

  識別指定金鑰對中的橢圓曲線規格。寄件者和收件人的金鑰對必須具有相同的曲線規格。

  有效值：`ECC_NIST_P256`、`ECC_NIS_P384`、`ECC_NIST_P512`
+ **（選用） 授予權杖的清單**

  如果您使用[授權](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html)控制對 AWS KMS ECDH keyring 中 KMS 金鑰的存取，您必須在初始化 keyring 時提供所有必要的授予字符。

------
#### [ C\# / .NET ]

下列範例會使用寄件者的 KMS 金鑰、寄件者的公有金鑰和收件人的公有金鑰，使用 建立 AWS KMS ECDH keyring。此範例使用選用`SenderPublicKey`參數來提供寄件者的公有金鑰。如果您未提供寄件者的公有金鑰， keyring 會呼叫 AWS KMS 來擷取寄件者的公有金鑰。寄件者和收件人的金鑰對都在`ECC_NIST_P256`曲線上。

```
// Instantiate material providers
var materialProviders = new MaterialProviders(new MaterialProvidersConfig());

// Must be DER-encoded X.509 public keys
var BobPublicKey = new MemoryStream(new byte[] { });
var AlicePublicKey = new MemoryStream(new byte[] { });

// Create the AWS KMS ECDH static keyring
var staticConfiguration = new KmsEcdhStaticConfigurations
{
    KmsPrivateKeyToStaticPublicKey = new KmsPrivateKeyToStaticPublicKeyInput
    {
        SenderKmsIdentifier = "{{arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab}}",
        SenderPublicKey = BobPublicKey,
        RecipientPublicKey = AlicePublicKey
    }
};
	    
var createKeyringInput = new CreateAwsKmsEcdhKeyringInput
{
    CurveSpec = ECDHCurveSpec.{{ECC_NIST_P256}},
    KmsClient = new AmazonKeyManagementServiceClient(),
    KeyAgreementScheme = staticConfiguration
};

var keyring = materialProviders.CreateAwsKmsEcdhKeyring(createKeyringInput);
```

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

下列範例會使用寄件者的 KMS 金鑰、寄件者的公有金鑰和收件人的公有金鑰，使用 建立 AWS KMS ECDH keyring。此範例使用選用`senderPublicKey`參數來提供寄件者的公有金鑰。如果您未提供寄件者的公有金鑰， keyring 會呼叫 AWS KMS 來擷取寄件者的公有金鑰。寄件者和收件人的金鑰對都在`ECC_NIST_P256`曲線上。

```
// Retrieve public keys
// Must be DER-encoded X.509 public keys                                
ByteBuffer BobPublicKey = getPublicKeyBytes("{{arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab}}");
        ByteBuffer AlicePublicKey = getPublicKeyBytes("{{arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321}}"); 

// Create the AWS KMS ECDH static keyring
        final CreateAwsKmsEcdhKeyringInput senderKeyringInput =
          CreateAwsKmsEcdhKeyringInput.builder()
            .kmsClient(KmsClient.create())
            .curveSpec(ECDHCurveSpec.{{ECC_NIST_P256}})
            .KeyAgreementScheme(
              KmsEcdhStaticConfigurations.builder()
                .KmsPrivateKeyToStaticPublicKey(
                  KmsPrivateKeyToStaticPublicKeyInput.builder()
                    .senderKmsIdentifier("{{arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab}}")
                    .senderPublicKey(BobPublicKey)
                    .recipientPublicKey(AlicePublicKey)
                    .build()).build()).build();
```

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

下列範例會使用寄件者的 KMS 金鑰、寄件者的公有金鑰和收件人的公有金鑰，使用 建立 AWS KMS ECDH keyring。此範例使用選用`senderPublicKey`參數來提供寄件者的公有金鑰。如果您未提供寄件者的公有金鑰， keyring 會呼叫 AWS KMS 來擷取寄件者的公有金鑰。寄件者和收件人的金鑰對都在`ECC_NIST_P256`曲線上。

```
import boto3
from aws_cryptographic_materialproviders.mpl.models import (
    CreateAwsKmsEcdhKeyringInput,
    KmsEcdhStaticConfigurationsKmsPrivateKeyToStaticPublicKey,
    KmsPrivateKeyToStaticPublicKeyInput,
)
from aws_cryptography_primitives.smithygenerated.aws_cryptography_primitives.models import ECDHCurveSpec

# Instantiate the material providers library
mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
    config=MaterialProvidersConfig()
)

# Retrieve public keys
# Must be DER-encoded X.509 public keys
bob_public_key = get_public_key_bytes("{{arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab}}")
alice_public_key = get_public_key_bytes("{{arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321}}")

# Create the AWS KMS ECDH static keyring
sender_keyring_input = CreateAwsKmsEcdhKeyringInput(
    kms_client = boto3.client('kms', region_name="us-west-2"),
    curve_spec = ECDHCurveSpec.{{ECC_NIST_P256}},
    key_agreement_scheme = KmsEcdhStaticConfigurationsKmsPrivateKeyToStaticPublicKey(
        KmsPrivateKeyToStaticPublicKeyInput(
            sender_kms_identifier = "{{arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab}}",
            sender_public_key = bob_public_key,
            recipient_public_key = alice_public_key,

        )
    )
)

keyring = mat_prov.create_aws_kms_ecdh_keyring(sender_keyring_input)
```

------
#### [ Rust ]

下列範例會使用寄件者的 KMS 金鑰、寄件者的公有金鑰和收件人的公有金鑰，使用 建立 AWS KMS ECDH keyring。此範例使用選用`sender_public_key`參數來提供寄件者的公有金鑰。如果您未提供寄件者的公有金鑰， keyring 會呼叫 AWS KMS 來擷取寄件者的公有金鑰。

```
// Instantiate the AWS Encryption SDK client
let esdk_config = AwsEncryptionSdkConfig::builder().build()?;
let esdk_client = esdk_client::Client::from_conf(esdk_config)?;

// Create the AWS KMS client
let sdk_config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
let kms_client = aws_sdk_kms::Client::new(&sdk_config);

// Optional: Create your 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()),
]);

// Retrieve public keys
// Must be DER-encoded X.509 keys
let public_key_file_content_sender = std::fs::read_to_string(Path::new(EXAMPLE_KMS_ECC_PUBLIC_KEY_FILENAME_SENDER))?;
let parsed_public_key_file_content_sender = parse(public_key_file_content_sender)?;
let public_key_sender_utf8_bytes = parsed_public_key_file_content_sender.contents();

let public_key_file_content_recipient = std::fs::read_to_string(Path::new(EXAMPLE_KMS_ECC_PUBLIC_KEY_FILENAME_RECIPIENT))?;
let parsed_public_key_file_content_recipient = parse(public_key_file_content_recipient)?;
let public_key_recipient_utf8_bytes = parsed_public_key_file_content_recipient.contents();

// Create KmsPrivateKeyToStaticPublicKeyInput
let kms_ecdh_static_configuration_input =
    KmsPrivateKeyToStaticPublicKeyInput::builder()
        .sender_kms_identifier({{arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab}})
        // Must be a UTF8 DER-encoded X.509 public key
        .sender_public_key(public_key_sender_utf8_bytes)
        // Must be a UTF8 DER-encoded X.509 public key
        .recipient_public_key(public_key_recipient_utf8_bytes)
        .build()?;

let kms_ecdh_static_configuration = KmsEcdhStaticConfigurations::KmsPrivateKeyToStaticPublicKey(kms_ecdh_static_configuration_input);

// Instantiate the material providers library
let mpl_config = MaterialProvidersConfig::builder().build()?;
let mpl = mpl_client::Client::from_conf(mpl_config)?;

// Create AWS KMS ECDH keyring
let kms_ecdh_keyring = mpl
    .create_aws_kms_ecdh_keyring()
    .kms_client(kms_client)
    .curve_spec(ecdh_curve_spec)
    .key_agreement_scheme(kms_ecdh_static_configuration)
    .send()
    .await?;
```

------
#### [ Go ]

```
import (
    "context"
    
	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"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/kms"
)

// Instantiate the AWS Encryption SDK client
encryptionClient, err := client.NewClient(esdktypes.AwsEncryptionSdkConfig{})
if err != nil {
    panic(err)
}

// Create an AWS KMS client
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
    panic(err)
}
kmsClient := kms.NewFromConfig(cfg, func(o *kms.Options) {
    o.Region = KmsKeyRegion
})

// 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",
}

// Retrieve public keys
// Must be DER-encoded X.509 keys
publicKeySender, err := utils.LoadPublicKeyFromPEM(kmsEccPublicKeyFileNameSender)
if err != nil {
    panic(err)
}
publicKeyRecipient, err := utils.LoadPublicKeyFromPEM(kmsEccPublicKeyFileNameRecipient)
if err != nil {
    panic(err)
}

// Create KmsPrivateKeyToStaticPublicKeyInput
kmsEcdhStaticConfigurationInput := mpltypes.KmsPrivateKeyToStaticPublicKeyInput{
    RecipientPublicKey:  publicKeyRecipient,
    SenderKmsIdentifier: {{arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab}},
    SenderPublicKey:     publicKeySender,
}
kmsEcdhStaticConfiguration := &mpltypes.KmsEcdhStaticConfigurationsMemberKmsPrivateKeyToStaticPublicKey{
    Value: kmsEcdhStaticConfigurationInput,
}

// Instantiate the material providers library
matProv, err := mpl.NewClient(mpltypes.MaterialProvidersConfig{})
if err != nil {
    panic(err)
}

// Create AWS KMS ECDH keyring
awsKmsEcdhKeyringInput := mpltypes.CreateAwsKmsEcdhKeyringInput{
    CurveSpec:          ecdhCurveSpec,
    KeyAgreementScheme: kmsEcdhStaticConfiguration,
    KmsClient:          kmsClient,
}
awsKmsEcdhKeyring, err := matProv.CreateAwsKmsEcdhKeyring(context.Background(), awsKmsEcdhKeyringInput)
if err != nil {
    panic(err)
}
```

------

## 建立 AWS KMS ECDH 探索 keyring
<a name="kms-ecdh-discovery"></a>

解密時，最佳實務是指定 AWS Encryption SDK 可以使用的金鑰。若要遵循此最佳實務，請使用具有`KmsPrivateKeyToStaticPublicKey`金鑰協議結構描述的 AWS KMS ECDH keyring。不過，您也可以建立 AWS KMS ECDH 探索 keyring，也就是可解密指定 KMS 金鑰對之公有金鑰符合存放在訊息加密文字上*之收件人*公有金鑰的任何訊息的 AWS KMS ECDH keyring。

**重要**  
當您使用`KmsPublicKeyDiscovery`金鑰協議結構描述解密訊息時，您接受所有公有金鑰，無論誰擁有它。

若要使用`KmsPublicKeyDiscovery`金鑰協議結構描述初始化 AWS KMS ECDH keyring，請提供下列值：
+ **收件人的 AWS KMS key ID**

  必須識別`KeyUsage`值為 的非對稱 NIST 建議的橢圓曲線 (ECC) KMS 金鑰對`KEY_AGREEMENT`。
+ **曲線規格**

  識別收件人 KMS 金鑰對中的橢圓曲線規格。

  有效值：`ECC_NIST_P256`、`ECC_NIS_P384`、`ECC_NIST_P512`
+ **（選用） 授予權杖的清單**

  如果您使用[授權](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html)控制對 AWS KMS ECDH keyring 中 KMS 金鑰的存取，您必須在初始化 keyring 時提供所有必要的授予字符。

------
#### [ C\# / .NET ]

下列範例會在`ECC_NIST_P256`曲線上建立具有 KMS 金鑰對的 AWS KMS ECDH 探索 keyring。您必須擁有指定 KMS 金鑰對的 [kms:GetPublicKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GetPublicKey.html) 和 [kms:DeriveSharedSecret](https://docs.aws.amazon.com/kms/latest/APIReference/API_DeriveSharedSecret.html) 許可。此 keyring 可以解密任何訊息，其中指定 KMS 金鑰對的公有金鑰符合存放在訊息加密文字上的收件人公有金鑰。

```
// Instantiate material providers
var materialProviders = new MaterialProviders(new MaterialProvidersConfig());

// Create the AWS KMS ECDH discovery keyring
var discoveryConfiguration = new KmsEcdhStaticConfigurations
{
    KmsPublicKeyDiscovery = new KmsPublicKeyDiscoveryInput
    {
        RecipientKmsIdentifier = "{{arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321}}"
    }
		    
};
var createKeyringInput = new CreateAwsKmsEcdhKeyringInput
{
    CurveSpec = ECDHCurveSpec.{{ECC_NIST_P256}},
    KmsClient = new AmazonKeyManagementServiceClient(),
    KeyAgreementScheme = discoveryConfiguration
};
var keyring = materialProviders.CreateAwsKmsEcdhKeyring(createKeyringInput);
```

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

下列範例會在`ECC_NIST_P256`曲線上建立具有 KMS 金鑰對的 AWS KMS ECDH 探索 keyring。您必須擁有指定 KMS 金鑰對的 [kms:GetPublicKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GetPublicKey.html) 和 [kms:DeriveSharedSecret](https://docs.aws.amazon.com/kms/latest/APIReference/API_DeriveSharedSecret.html) 許可。此 keyring 可以解密任何訊息，其中指定 KMS 金鑰對的公有金鑰符合存放在訊息加密文字上的收件人公有金鑰。

```
// Create the AWS KMS ECDH discovery keyring
final CreateAwsKmsEcdhKeyringInput recipientKeyringInput =
  CreateAwsKmsEcdhKeyringInput.builder()
    .kmsClient(KmsClient.create())
    .curveSpec(ECDHCurveSpec.{{ECC_NIST_P256}})
    .KeyAgreementScheme(
      KmsEcdhStaticConfigurations.builder()
        .KmsPublicKeyDiscovery(
          KmsPublicKeyDiscoveryInput.builder()
            .recipientKmsIdentifier("{{arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321}}").build()
        ).build())
    .build();
```

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

下列範例會在`ECC_NIST_P256`曲線上建立具有 KMS 金鑰對的 AWS KMS ECDH 探索 keyring。您必須擁有指定 KMS 金鑰對的 [kms:GetPublicKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GetPublicKey.html) 和 [kms:DeriveSharedSecret](https://docs.aws.amazon.com/kms/latest/APIReference/API_DeriveSharedSecret.html) 許可。此 keyring 可以解密任何訊息，其中指定 KMS 金鑰對的公有金鑰符合存放在訊息加密文字上的收件人公有金鑰。

```
import boto3
from aws_cryptographic_materialproviders.mpl.models import (
    CreateAwsKmsEcdhKeyringInput,
    KmsEcdhStaticConfigurationsKmsPublicKeyDiscovery,
    KmsPublicKeyDiscoveryInput,
)
from aws_cryptography_primitives.smithygenerated.aws_cryptography_primitives.models import ECDHCurveSpec

# Instantiate the material providers library
mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
    config=MaterialProvidersConfig()
)

# Create the AWS KMS ECDH discovery keyring
create_keyring_input = CreateAwsKmsEcdhKeyringInput(
    kms_client = boto3.client('kms', region_name="us-west-2"),
    curve_spec = ECDHCurveSpec.{{ECC_NIST_P256}},
    key_agreement_scheme = KmsEcdhStaticConfigurationsKmsPublicKeyDiscovery(
        KmsPublicKeyDiscoveryInput(
            recipient_kms_identifier = "{{arn:aws:kms:us-west-2:111122223333:key/0987dcba-09fe-87dc-65ba-ab0987654321}}",
        )
    )
)

keyring = mat_prov.create_aws_kms_ecdh_keyring(create_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)?;

// Create the AWS KMS client
let sdk_config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
let kms_client = aws_sdk_kms::Client::new(&sdk_config);

// Optional: Create your 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()),
]);

// Create KmsPublicKeyDiscoveryInput
let kms_ecdh_discovery_static_configuration_input =
    KmsPublicKeyDiscoveryInput::builder()
        .recipient_kms_identifier(ecc_recipient_key_arn)
        .build()?;

let kms_ecdh_discovery_static_configuration = KmsEcdhStaticConfigurations::KmsPublicKeyDiscovery(kms_ecdh_discovery_static_configuration_input);

// Instantiate the material providers library
let mpl_config = MaterialProvidersConfig::builder().build()?;
let mpl = mpl_client::Client::from_conf(mpl_config)?;

// Create AWS KMS ECDH discovery keyring
let kms_ecdh_discovery_keyring = mpl
    .create_aws_kms_ecdh_keyring()
    .kms_client(kms_client.clone())
    .curve_spec(ecdh_curve_spec)
    .key_agreement_scheme(kms_ecdh_discovery_static_configuration)
    .send()
    .await?;
```

------
#### [ Go ]

```
import (
    "context"
    
	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"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/kms"
)

// Instantiate the AWS Encryption SDK client
encryptionClient, err := client.NewClient(esdktypes.AwsEncryptionSdkConfig{})
if err != nil {
    panic(err)
}

// Create an AWS KMS client
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
    panic(err)
}
kmsClient := kms.NewFromConfig(cfg, func(o *kms.Options) {
    o.Region = KmsKeyRegion
})

// 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",
}

// Create KmsPublicKeyDiscoveryInput
kmsEcdhDiscoveryStaticConfigurationInput := mpltypes.KmsPublicKeyDiscoveryInput{
    RecipientKmsIdentifier: eccRecipientKeyArn,
}
kmsEcdhDiscoveryStaticConfiguration := &mpltypes.KmsEcdhStaticConfigurationsMemberKmsPublicKeyDiscovery{
    Value: kmsEcdhDiscoveryStaticConfigurationInput,
}

// Instantiate the material providers library
matProv, err := mpl.NewClient(mpltypes.MaterialProvidersConfig{})
if err != nil {
    panic(err)
}

// Create AWS KMS ECDH discovery keyring
awsKmsEcdhDiscoveryKeyringInput := mpltypes.CreateAwsKmsEcdhKeyringInput{
    CurveSpec:          ecdhCurveSpec,
    KeyAgreementScheme: kmsEcdhDiscoveryStaticConfiguration,
    KmsClient:          kmsClient,
}
awsKmsEcdhDiscoveryKeyring, err := matProv.CreateAwsKmsEcdhKeyring(context.Background(), awsKmsEcdhDiscoveryKeyringInput)
if err != nil {
    panic(err)
}
```

------