

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 원시 ECDH 키링
<a name="use-raw-ecdh-keyring"></a>

원시 ECDH 키링은 사용자가 제공하는 타원 곡선 퍼블릭-프라이빗 키 페어를 사용하여 두 당사자 간에 공유 래핑 키를 도출합니다. 먼저 키링은 발신자의 프라이빗 키, 수신자의 퍼블릭 키 및 ECDH(Elliptic Curve Diffie-Hellman) 키 계약 알고리즘을 사용하여 공유 보안 암호를 추출합니다. 그런 다음 키링은 공유 보안 암호를 사용하여 데이터 암호화 키를 보호하는 공유 래핑 키를 파생합니다. 가 (`KDF_CTR_HMAC_SHA384`)를 AWS Encryption SDK 사용하여 공유 래핑 키를 파생하는 키 파생 함수는 [키 파생에 대한 NIST 권장 사항을](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-108r1-upd1.pdf) 준수합니다.

키 파생 함수는 64바이트의 키 구성 요소를 반환합니다. 양 당사자가 올바른 키 구성 요소를 사용하도록 하기 위해는 처음 32바이트를 커밋 키로 사용하고 마지막 32바이트를 공유 래핑 키로 AWS Encryption SDK 사용합니다. 복호화 시 키링이 메시지 헤더 사이퍼텍스트에 저장된 동일한 커밋 키와 공유 래핑 키를 재현할 수 없는 경우 작업이 실패합니다. 예를 들어 **Alice의** 프라이빗 키와 **Bob의** 퍼블릭 키로 구성된 키링으로 데이터를 암호화하는 경우 **Bob의** 프라이빗 키와 **Alice의** 퍼블릭 키로 구성된 키링은 동일한 커밋 키와 공유 래핑 키를 재현하고 데이터를 해독할 수 있습니다. Bob의 퍼블릭 키가 AWS KMS key 페어에서 가져온 경우 Bob은 [AWS KMS ECDH 키링](use-kms-ecdh-keyring.md)을 생성하여 데이터를 해독할 수 있습니다.

원시 ECDH 키링은 AES-GCM을 사용하여 대칭 키로 데이터를 암호화합니다. 그런 다음 AES-GCM을 사용하여 파생된 공유 래핑 키로 데이터 키를 봉투 암호화합니다. 각 Raw ECDH 키링에는 공유 래핑 키가 하나만 있을 수 있지만, 단독으로 또는 다른 키링과 함께 여러 Raw ECDH 키링을 [다중 키링](use-multi-keyring.md)에 포함할 수 있습니다.

사용자는 가급적이면 하드웨어 보안 모듈(HSM) 또는 키 관리 시스템에서 프라이빗 키를 생성, 저장 및 보호할 책임이 있습니다. 발신자와 수신자의 키 페어는 동일한 타원 곡선에 많이 있습니다. 는 다음과 같은 타원 곡선 사양을 AWS Encryption SDK 지원합니다.
+ `ECC_NIST_P256`
+ `ECC_NIST_P384`
+ `ECC_NIST_P512`

**프로그래밍 언어 호환성**  
원시 ECDH 키링은 [암호화 자료 공급자 라이브러리](https://github.com/aws/aws-cryptographic-material-providers-library)(MPL) 버전 1.5.0에 도입되었으며 다음 프로그래밍 언어 및 버전에서 지원됩니다.
+ 의 버전 3.*x* AWS Encryption SDK for Java
+ for .NET 버전 AWS Encryption SDK 4.*x* 이상
+ 선택적 MPL 종속성과 함께 사용하는 AWS Encryption SDK for Python경우 버전 4.*x*.
+  AWS Encryption SDK for Rust 버전 1.*x* 
+ Go AWS Encryption SDK 용의 버전 0.1.*x* 이상

## 원시 ECDH 키링 생성
<a name="raw-ecdh-create"></a>

원시 ECDH 키링은 `RawPrivateKeyToStaticPublicKey`, 및 `EphemeralPrivateKeyToStaticPublicKey`의 세 가지 주요 계약 스키마를 지원합니다`PublicKeyDiscovery`. 선택하는 키 계약 스키마에 따라 수행할 수 있는 암호화 작업과 키 구성 요소가 수집되는 방식이 결정됩니다.

**Topics**
+ [RawPrivateKeyToStaticPublicKey](#raw-ecdh-RawPrivateKeyToStaticPublicKey)
+ [EphemeralPrivateKeyToStaticPublicKey](#raw-ecdh-EphemeralPrivateKeyToStaticPublicKey)
+ [PublicKeyDiscovery](#raw-ecdh-PublicKeyDiscovery)

### RawPrivateKeyToStaticPublicKey
<a name="raw-ecdh-RawPrivateKeyToStaticPublicKey"></a>

`RawPrivateKeyToStaticPublicKey` 키 계약 스키마를 사용하여 키링에서 발신자의 프라이빗 키와 수신자의 퍼블릭 키를 정적으로 구성합니다. 이 키 계약 스키마는 데이터를 암호화하고 해독할 수 있습니다.

`RawPrivateKeyToStaticPublicKey` 키 계약 스키마를 사용하여 원시 ECDH 키링을 초기화하려면 다음 값을 제공합니다.
+ **발신자의 프라이빗 키**

  [RFC 595](https://tools.ietf.org/html/rfc5958#section-2)8에 정의된 대로 발신자의 PEM 인코딩 프라이빗 키(PKCS \#8 PrivateKeyInfo 구조)를 제공해야 합니다.
+ **수신자의 퍼블릭 키**

  RFC 5280에 정의된 대로 `SubjectPublicKeyInfo` (SPKI)라고도 하는 수신자의 DER 인코딩 X.509 퍼블릭 키를 제공해야 합니다. [https://tools.ietf.org/html/rfc5280](https://tools.ietf.org/html/rfc5280) 

  비대칭 키 계약 KMS 키 페어의 퍼블릭 키 또는 외부에서 생성된 키 페어의 퍼블릭 키를 지정할 수 있습니다 AWS.
+ **곡선 사양**

  지정된 키 페어에서 타원 곡선 사양을 식별합니다. 발신자와 수신자의 키 페어 모두 곡선 사양이 동일해야 합니다.

  유효한 값: `ECC_NIST_P256`, `ECC_NIS_P384`, `ECC_NIST_P512` 

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

```
// Instantiate material providers
var materialProviders = new MaterialProviders(new MaterialProvidersConfig());
	    var BobPrivateKey = new MemoryStream(new byte[] { });
	    var AlicePublicKey = new MemoryStream(new byte[] { });

	    // Create the Raw ECDH static keyring
	    var staticConfiguration = new RawEcdhStaticConfigurations()
	    {
		    RawPrivateKeyToStaticPublicKey = new RawPrivateKeyToStaticPublicKeyInput
		    {
			    SenderStaticPrivateKey = BobPrivateKey,
			    RecipientPublicKey = AlicePublicKey
		    }
	    };
	    
	    var createKeyringInput = new CreateRawEcdhKeyringInput() 
	    {
		    CurveSpec = ECDHCurveSpec.{{ECC_NIST_P256}},
		    KeyAgreementScheme = staticConfiguration 
	    };

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

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

다음 Java 예제에서는 `RawPrivateKeyToStaticPublicKey` 키 계약 스키마를 사용하여 발신자의 프라이빗 키와 수신자의 퍼블릭 키를 정적으로 구성합니다. 두 키 페어 모두 `ECC_NIST_P256` 곡선에 있습니다.

```
private static void StaticRawKeyring() {
    // Instantiate material providers
    final MaterialProviders materialProviders =
      MaterialProviders.builder()
        .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
        .build();

    KeyPair senderKeys = GetRawEccKey();
    KeyPair recipient = GetRawEccKey();

    // Create the Raw ECDH static keyring
    final CreateRawEcdhKeyringInput rawKeyringInput =
      CreateRawEcdhKeyringInput.builder()
        .curveSpec(ECDHCurveSpec.{{ECC_NIST_P256}})
        .KeyAgreementScheme(
          RawEcdhStaticConfigurations.builder()
            .RawPrivateKeyToStaticPublicKey(
                RawPrivateKeyToStaticPublicKeyInput.builder()
                  // Must be a PEM-encoded private key
                  .senderStaticPrivateKey(ByteBuffer.wrap(senderKeys.getPrivate().getEncoded()))
                  // Must be a DER-encoded X.509 public key
                  .recipientPublicKey(ByteBuffer.wrap(recipient.getPublic().getEncoded()))
                  .build()
            )
            .build()
        ).build();

    final IKeyring staticKeyring = materialProviders.CreateRawEcdhKeyring(rawKeyringInput);
}
```

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

다음 Python 예제에서는 `RawEcdhStaticConfigurationsRawPrivateKeyToStaticPublicKey` 키 계약 스키마를 사용하여 발신자의 프라이빗 키와 수신자의 퍼블릭 키를 정적으로 구성합니다. 두 키 페어 모두 `ECC_NIST_P256` 곡선에 있습니다.

```
import boto3
from aws_cryptographic_materialproviders.mpl.models import (
    CreateRawEcdhKeyringInput,
    RawEcdhStaticConfigurationsRawPrivateKeyToStaticPublicKey,
    RawPrivateKeyToStaticPublicKeyInput,
)
from aws_cryptography_primitives.smithygenerated.aws_cryptography_primitives.models import ECDHCurveSpec

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

# Must be a PEM-encoded private key
bob_private_key = get_private_key_bytes()
# Must be a DER-encoded X.509 public key
alice_public_key = get_public_key_bytes()

# Create the raw ECDH static keyring
raw_keyring_input = CreateRawEcdhKeyringInput(
    curve_spec = ECDHCurveSpec.{{ECC_NIST_P256}},
    key_agreement_scheme = RawEcdhStaticConfigurationsRawPrivateKeyToStaticPublicKey(
        RawPrivateKeyToStaticPublicKeyInput(
            sender_static_private_key = bob_private_key,
            recipient_public_key = alice_public_key,
        )
    )
)

keyring = mat_prov.create_raw_ecdh_keyring(raw_keyring_input)
```

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

다음 Python 예제에서는 `raw_ecdh_static_configuration` 키 계약 스키마를 사용하여 발신자의 프라이빗 키와 수신자의 퍼블릭 키를 정적으로 구성합니다. 두 키 페어 모두 동일한 곡선에 있어야 합니다.

```
// Instantiate the AWS Encryption SDK client
let esdk_config = AwsEncryptionSdkConfig::builder().build()?;
let esdk_client = esdk_client::Client::from_conf(esdk_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 keyring input
let raw_ecdh_static_configuration_input =
    RawPrivateKeyToStaticPublicKeyInput::builder()
        // Must be a UTF8 PEM-encoded private key
        .sender_static_private_key(private_key_sender_utf8_bytes)
        // Must be a UTF8 DER-encoded X.509 public key
        .recipient_public_key(public_key_recipient_utf8_bytes)
        .build()?;

let raw_ecdh_static_configuration = RawEcdhStaticConfigurations::RawPrivateKeyToStaticPublicKey(raw_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 raw ECDH static keyring
let raw_ecdh_keyring = mpl
    .create_raw_ecdh_keyring()
    .curve_spec(ecdh_curve_spec)
    .key_agreement_scheme(raw_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"
)

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

// Optional: Create your 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 keyring input
rawEcdhStaticConfigurationInput := mpltypes.RawPrivateKeyToStaticPublicKeyInput{
    SenderStaticPrivateKey: privateKeySender,
    RecipientPublicKey:     publicKeyRecipient,
}
rawECDHStaticConfiguration := &mpltypes.RawEcdhStaticConfigurationsMemberRawPrivateKeyToStaticPublicKey{
    Value: rawEcdhStaticConfigurationInput,
}
rawEcdhKeyRingInput := mpltypes.CreateRawEcdhKeyringInput{
    CurveSpec:          ecdhCurveSpec,
    KeyAgreementScheme: rawECDHStaticConfiguration,
}

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

// Create raw ECDH static keyring
rawEcdhKeyring, err := matProv.CreateRawEcdhKeyring(context.Background(), rawEcdhKeyRingInput)
if err != nil {
    panic(err)
}
```

------

### EphemeralPrivateKeyToStaticPublicKey
<a name="raw-ecdh-EphemeralPrivateKeyToStaticPublicKey"></a>

키 계약 스키마로 구성된 `EphemeralPrivateKeyToStaticPublicKey` 키링은 로컬에서 새 키 페어를 생성하고 각 암호화 호출에 대해 고유한 공유 래핑 키를 도출합니다.

이 키 계약 스키마는 메시지만 암호화할 수 있습니다. `EphemeralPrivateKeyToStaticPublicKey` 키 계약 스키마로 암호화된 메시지를 복호화하려면 동일한 수신자의 퍼블릭 키로 구성된 검색 키 계약 스키마를 사용해야 합니다. 복호화하려면 [`PublicKeyDiscovery`](#raw-ecdh-PublicKeyDiscovery) 키 계약 알고리즘과 함께 원시 ECDH 키링을 사용하거나 수신자의 퍼블릭 키가 비대칭 키 계약 KMS 키 페어에서 가져온 경우 [KmsPublicKeyDiscovery](use-kms-ecdh-keyring.md#kms-ecdh-discovery) 키 계약 스키마와 함께 AWS KMS ECDH 키링을 사용할 수 있습니다.

`EphemeralPrivateKeyToStaticPublicKey` 키 계약 스키마를 사용하여 원시 ECDH 키링을 초기화하려면 다음 값을 제공합니다.
+ **수신자의 퍼블릭 키**

  RFC 5280에 정의된 대로 `SubjectPublicKeyInfo` (SPKI)라고도 하는 수신자의 DER 인코딩 X.509 퍼블릭 키를 제공해야 합니다. [https://tools.ietf.org/html/rfc5280](https://tools.ietf.org/html/rfc5280) 

  비대칭 키 계약 KMS 키 페어의 퍼블릭 키 또는 외부에서 생성된 키 페어의 퍼블릭 키를 지정할 수 있습니다 AWS.
+ **곡선 사양**

  지정된 퍼블릭 키에서 타원 곡선 사양을 식별합니다.

  암호화 시 키링은 지정된 곡선에 새 키 페어를 생성하고 새 프라이빗 키와 지정된 퍼블릭 키를 사용하여 공유 래핑 키를 도출합니다.

  유효한 값: `ECC_NIST_P256`, `ECC_NIS_P384`, `ECC_NIST_P512` 

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

다음 예시에서는 `EphemeralPrivateKeyToStaticPublicKey` 키 계약 스키마를 사용하여 원시 ECDH 키링을 생성합니다. 암호화 시 키링은 지정된 `ECC_NIST_P256` 곡선에 로컬로 새 키 페어를 생성합니다.

```
// Instantiate material providers
var materialProviders = new MaterialProviders(new MaterialProvidersConfig());
	    var AlicePublicKey = new MemoryStream(new byte[] { });

	    // Create the Raw ECDH ephemeral keyring
	    var ephemeralConfiguration = new RawEcdhStaticConfigurations()
	    {
		    EphemeralPrivateKeyToStaticPublicKey = new EphemeralPrivateKeyToStaticPublicKeyInput
		    {
			    RecipientPublicKey = AlicePublicKey
		    }
	    };
	    
	    var createKeyringInput = new CreateRawEcdhKeyringInput() 
	    {
		    CurveSpec = ECDHCurveSpec.{{ECC_NIST_P256}},
		    KeyAgreementScheme = ephemeralConfiguration
	    };

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

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

다음 예시에서는 `EphemeralPrivateKeyToStaticPublicKey` 키 계약 스키마를 사용하여 원시 ECDH 키링을 생성합니다. 암호화 시 키링은 지정된 `ECC_NIST_P256` 곡선에 로컬로 새 키 페어를 생성합니다.

```
private static void EphemeralRawEcdhKeyring() {
    // Instantiate material providers
    final MaterialProviders materialProviders =
      MaterialProviders.builder()
        .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
        .build();

    ByteBuffer recipientPublicKey = getPublicKeyBytes();

    // Create the Raw ECDH ephemeral keyring
    final CreateRawEcdhKeyringInput ephemeralInput =
      CreateRawEcdhKeyringInput.builder()
        .curveSpec(ECDHCurveSpec.{{ECC_NIST_P256}})
        .KeyAgreementScheme(
          RawEcdhStaticConfigurations.builder()
            .EphemeralPrivateKeyToStaticPublicKey(
              EphemeralPrivateKeyToStaticPublicKeyInput.builder()
                .recipientPublicKey(recipientPublicKey)
                .build()
            )
            .build()
        ).build();

    final IKeyring ephemeralKeyring = materialProviders.CreateRawEcdhKeyring(ephemeralInput);
}
```

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

다음 예시에서는 키 계약 스키마를 사용하여 Raw ECDH `RawEcdhStaticConfigurationsEphemeralPrivateKeyToStaticPublicKey` 키링을 생성합니다. 암호화 시 키링은 지정된 `ECC_NIST_P256` 곡선에 로컬로 새 키 페어를 생성합니다.

```
import boto3
from aws_cryptographic_materialproviders.mpl.models import (
    CreateRawEcdhKeyringInput,
    RawEcdhStaticConfigurationsEphemeralPrivateKeyToStaticPublicKey,
    EphemeralPrivateKeyToStaticPublicKeyInput,
)
from aws_cryptography_primitives.smithygenerated.aws_cryptography_primitives.models import ECDHCurveSpec

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

# Your get_public_key_bytes must return a DER-encoded X.509 public key
recipient_public_key = get_public_key_bytes()

# Create the raw ECDH ephemeral private key keyring
ephemeral_input = CreateRawEcdhKeyringInput(
    curve_spec = ECDHCurveSpec.{{ECC_NIST_P256}},
    key_agreement_scheme = RawEcdhStaticConfigurationsEphemeralPrivateKeyToStaticPublicKey(
        EphemeralPrivateKeyToStaticPublicKeyInput(
            recipient_public_key = recipient_public_key,
        )
    )
)

keyring = mat_prov.create_raw_ecdh_keyring(ephemeral_input)
```

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

다음 예제에서는 `ephemeral_raw_ecdh_static_configuration` 키 계약 스키마를 사용하여 Raw ECDH 키링을 생성합니다. 암호화 시 키링은 지정된 곡선에 로컬로 새 키 페어를 생성합니다.

```
// Instantiate the AWS Encryption SDK client
let esdk_config = AwsEncryptionSdkConfig::builder().build()?;
let esdk_client = esdk_client::Client::from_conf(esdk_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()),
]);

// Load public key from UTF-8 encoded PEM files into a DER encoded public key.
let public_key_file_content = std::fs::read_to_string(Path::new(EXAMPLE_ECC_PUBLIC_KEY_FILENAME_RECIPIENT))?;
let parsed_public_key_file_content = parse(public_key_file_content)?;
let public_key_recipient_utf8_bytes = parsed_public_key_file_content.contents();

// Create EphemeralPrivateKeyToStaticPublicKeyInput
let ephemeral_raw_ecdh_static_configuration_input =
    EphemeralPrivateKeyToStaticPublicKeyInput::builder()
        // Must be a UTF8 DER-encoded X.509 public key
        .recipient_public_key(public_key_recipient_utf8_bytes)
        .build()?;

let ephemeral_raw_ecdh_static_configuration =
    RawEcdhStaticConfigurations::EphemeralPrivateKeyToStaticPublicKey(ephemeral_raw_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 raw ECDH ephemeral private key keyring
let ephemeral_raw_ecdh_keyring = mpl
    .create_raw_ecdh_keyring()
    .curve_spec(ecdh_curve_spec)
    .key_agreement_scheme(ephemeral_raw_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"
)

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

// Optional: Create your 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",
}

// Load public key from UTF-8 encoded PEM files into a DER encoded public key
publicKeyRecipient, err := LoadPublicKeyFromPEM(eccPublicKeyFileNameRecipient)
if err != nil {
    panic(err)
}

// Create EphemeralPrivateKeyToStaticPublicKeyInput
ephemeralRawEcdhStaticConfigurationInput := mpltypes.EphemeralPrivateKeyToStaticPublicKeyInput{
    RecipientPublicKey: publicKeyRecipient,
}
ephemeralRawECDHStaticConfiguration :=
    mpltypes.RawEcdhStaticConfigurationsMemberEphemeralPrivateKeyToStaticPublicKey{
        Value: ephemeralRawEcdhStaticConfigurationInput,
    }

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

// Create raw ECDH ephemeral private key keyring
rawEcdhKeyRingInput := mpltypes.CreateRawEcdhKeyringInput{
    CurveSpec:          ecdhCurveSpec,
    KeyAgreementScheme: &ephemeralRawECDHStaticConfiguration,
}
ecdhKeyring, err := matProv.CreateRawEcdhKeyring(context.Background(), rawEcdhKeyRingInput)
if err != nil {
    panic(err)
}
```

------

### PublicKeyDiscovery
<a name="raw-ecdh-PublicKeyDiscovery"></a>

복호화할 때는에서 사용할 AWS Encryption SDK 수 있는 래핑 키를 지정하는 것이 가장 좋습니다. 이 모범 사례를 따르려면 발신자의 프라이빗 키와 수신자의 퍼블릭 키를 모두 지정하는 ECDH 키링을 사용합니다. 그러나 원시 ECDH 검색 키링, 즉 지정된 키의 퍼블릭 키가 메시지 사이퍼텍스트에 저장된 수신자의 퍼블릭 키와 일치하는 모든 메시지를 복호화할 수 있는 원시 ECDH 키링을 생성할 수도 있습니다. 이 키 계약 스키마는 메시지만 복호화할 수 있습니다.

**중요**  
`PublicKeyDiscovery` 키 계약 스키마를 사용하여 메시지를 복호화하는 경우 누가 소유하든 모든 퍼블릭 키를 수락합니다.

`PublicKeyDiscovery` 키 계약 스키마를 사용하여 원시 ECDH 키링을 초기화하려면 다음 값을 제공합니다.
+ **수신자의 정적 프라이빗 키**

  [RFC 595](https://tools.ietf.org/html/rfc5958#section-2)8에 정의된 대로 수신자의 PEM 인코딩 프라이빗 키(PKCS \#8 PrivateKeyInfo 구조)를 제공해야 합니다.
+ **곡선 사양**

  지정된 프라이빗 키에서 타원 곡선 사양을 식별합니다. 발신자와 수신자의 키 페어 모두 곡선 사양이 동일해야 합니다.

  유효한 값: `ECC_NIST_P256`, `ECC_NIS_P384`, `ECC_NIST_P512` 

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

다음 예시에서는 `PublicKeyDiscovery` 키 계약 스키마를 사용하여 원시 ECDH 키링을 생성합니다. 이 키링은 지정된 프라이빗 키의 퍼블릭 키가 메시지 사이퍼텍스트에 저장된 수신자의 퍼블릭 키와 일치하는 모든 메시지를 복호화할 수 있습니다.

```
// Instantiate material providers
var materialProviders = new MaterialProviders(new MaterialProvidersConfig());
	    var AlicePrivateKey = new MemoryStream(new byte[] { });

	    // Create the Raw ECDH discovery keyring
	    var discoveryConfiguration = new RawEcdhStaticConfigurations()
	    {
		    PublicKeyDiscovery = new PublicKeyDiscoveryInput
		    {
			    RecipientStaticPrivateKey = AlicePrivateKey
		    }
	    };
	    
	    var createKeyringInput = new CreateRawEcdhKeyringInput() 
	    {
		    CurveSpec = ECDHCurveSpec.ECC_NIST_P256,
		    KeyAgreementScheme = discoveryConfiguration 
	    };

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

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

다음 예시에서는 `PublicKeyDiscovery` 키 계약 스키마를 사용하여 원시 ECDH 키링을 생성합니다. 이 키링은 지정된 프라이빗 키의 퍼블릭 키가 메시지 사이퍼텍스트에 저장된 수신자의 퍼블릭 키와 일치하는 모든 메시지를 복호화할 수 있습니다.

```
private static void RawEcdhDiscovery() {
    // Instantiate material providers
    final MaterialProviders materialProviders =
      MaterialProviders.builder()
        .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
        .build();

    KeyPair recipient = GetRawEccKey();

    // Create the Raw ECDH discovery keyring
    final CreateRawEcdhKeyringInput rawKeyringInput =
      CreateRawEcdhKeyringInput.builder()
        .curveSpec(ECDHCurveSpec.{{ECC_NIST_P256}})
        .KeyAgreementScheme(
          RawEcdhStaticConfigurations.builder()
            .PublicKeyDiscovery(
              PublicKeyDiscoveryInput.builder()
                // Must be a PEM-encoded private key
                .recipientStaticPrivateKey(ByteBuffer.wrap(sender.getPrivate().getEncoded()))
                .build()
            )
            .build()
        ).build();

    final IKeyring publicKeyDiscovery  = materialProviders.CreateRawEcdhKeyring(rawKeyringInput);
}
```

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

다음 예시에서는 `RawEcdhStaticConfigurationsPublicKeyDiscovery` 키 계약 스키마를 사용하여 원시 ECDH 키링을 생성합니다. 이 키링은 지정된 프라이빗 키의 퍼블릭 키가 메시지 사이퍼텍스트에 저장된 수신자의 퍼블릭 키와 일치하는 모든 메시지를 복호화할 수 있습니다.

```
import boto3
from aws_cryptographic_materialproviders.mpl.models import (
    CreateRawEcdhKeyringInput,
    RawEcdhStaticConfigurationsPublicKeyDiscovery,
    PublicKeyDiscoveryInput,
)
from aws_cryptography_primitives.smithygenerated.aws_cryptography_primitives.models import ECDHCurveSpec

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

# Your get_private_key_bytes must return a PEM-encoded private key
recipient_private_key = get_private_key_bytes()

# Create the raw ECDH discovery keyring
raw_keyring_input = CreateRawEcdhKeyringInput(
    curve_spec = ECDHCurveSpec.{{ECC_NIST_P256}},
    key_agreement_scheme = RawEcdhStaticConfigurationsPublicKeyDiscovery(
        PublicKeyDiscoveryInput(
            recipient_static_private_key = recipient_private_key,
        )
    )
)

keyring = mat_prov.create_raw_ecdh_keyring(raw_keyring_input)
```

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

다음 예시에서는 `discovery_raw_ecdh_static_configuration` 키 계약 스키마를 사용하여 원시 ECDH 키링을 생성합니다. 이 키링은 지정된 프라이빗 키의 퍼블릭 키가 메시지 사이퍼텍스트에 저장된 수신자의 퍼블릭 키와 일치하는 모든 메시지를 복호화할 수 있습니다.

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

let mpl_config = MaterialProvidersConfig::builder().build()?;
let mpl = mpl_client::Client::from_conf(mpl_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()),
]);

// Load keys from UTF-8 encoded PEM files.
let mut file = File::open(Path::new(EXAMPLE_ECC_PRIVATE_KEY_FILENAME_RECIPIENT))?;
let mut private_key_recipient_utf8_bytes = Vec::new();
file.read_to_end(&mut private_key_recipient_utf8_bytes)?;

// Create PublicKeyDiscoveryInput
let discovery_raw_ecdh_static_configuration_input =
    PublicKeyDiscoveryInput::builder()
        // Must be a UTF8 PEM-encoded private key
        .recipient_static_private_key(private_key_recipient_utf8_bytes)
        .build()?;

let discovery_raw_ecdh_static_configuration =
    RawEcdhStaticConfigurations::PublicKeyDiscovery(discovery_raw_ecdh_static_configuration_input);

// Create raw ECDH discovery private key keyring
let discovery_raw_ecdh_keyring = mpl
    .create_raw_ecdh_keyring()
    .curve_spec(ecdh_curve_spec)
    .key_agreement_scheme(discovery_raw_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"
)

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

// Optional: Create your 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",
}

// Load keys from UTF-8 encoded PEM files.
privateKeyRecipient, err := os.ReadFile(eccPrivateKeyFileNameRecipient)
if err != nil {
    panic(err)
}

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

// Create PublicKeyDiscoveryInput
discoveryRawEcdhStaticConfigurationInput := mpltypes.PublicKeyDiscoveryInput{
    RecipientStaticPrivateKey: privateKeyRecipient,
}

discoveryRawEcdhStaticConfiguration := &mpltypes.RawEcdhStaticConfigurationsMemberPublicKeyDiscovery{
    Value: discoveryRawEcdhStaticConfigurationInput,
}

// Create raw ECDH discovery private key keyring
discoveryRawEcdhKeyringInput := mpltypes.CreateRawEcdhKeyringInput{
    CurveSpec:          ecdhCurveSpec,
    KeyAgreementScheme: discoveryRawEcdhStaticConfiguration,
}

discoveryRawEcdhKeyring, err := matProv.CreateRawEcdhKeyring(context.Background(), discoveryRawEcdhKeyringInput)
if err != nil {
    panic(err)
}
```

------