

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

# 原始 RSA keyring
<a name="use-raw-rsa-keyring"></a>

原始 RSA keyring 會使用您提供的 RSA 公有和私有金鑰，對本機記憶體中的資料金鑰執行非對稱加密和解密。您需要產生、存放和保護私有金鑰，最好是在硬體安全模組 (HSM) 或金鑰管理系統中。加密函數會根據 RSA 公開金鑰加密資料金鑰。解密函數會使用私有金鑰解密資料金鑰。您可以從數個 [RSA 填補模式](https://github.com/aws/aws-encryption-sdk-c/blob/master/include/aws/cryptosdk/cipher.h)中選擇。

加密和解密的原始 RSA keyring，必須包含非對稱公開金鑰和私有金鑰對。不過，您可以使用只有公有金鑰的原始 RSA keyring 來加密資料，也可以使用只有私有金鑰的原始 RSA keyring 來解密資料。您可以在[多 keyring 中包含任何原始 RSA keyring](use-multi-keyring.md)。如果您使用公有和私有金鑰設定原始 RSA keyring，請確定它們是相同金鑰對的一部分。的某些語言實作 AWS Encryption SDK 不會使用來自不同對的金鑰來建構原始 RSA keyring。其他人依賴您來驗證您的金鑰是否來自相同的金鑰對。

 原始 RSA keyring 等同於 中的 [JceMasterKey](https://aws.github.io/aws-encryption-sdk-java/com/amazonaws/encryptionsdk/jce/JceMasterKey.html) 和 中的 適用於 JAVA 的 AWS Encryption SDK [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)，並在與 RSA 非對稱加密金鑰搭配使用 適用於 Python 的 AWS Encryption SDK 時與其相互操作。您可以使用一個實作來加密資料，並利用使用相同包裝金鑰的任何其他實作來解密資料。如需詳細資訊，請參閱[Keyring 相容性](choose-keyring.md#keyring-compatibility)。

**注意**  
原始 RSA keyring 不支援非對稱 KMS 金鑰。如果您想要使用非對稱 RSA KMS 金鑰，下列程式設計語言支援使用非對稱 RSA 的 AWS KMS keyring AWS KMS keys：  
3.*x* 版 適用於 JAVA 的 AWS Encryption SDK
AWS Encryption SDK 適用於 .NET 的 4.*x* 版和更新版本
4.*x* 版 適用於 Python 的 AWS Encryption SDK，與選用[的密碼編譯材料提供者程式庫](https://github.com/aws/aws-cryptographic-material-providers-library) (MPL) 相依性搭配使用時。
適用於 Go 的 0.1.*x* AWS Encryption SDK 版或更新版本
如果您使用包含 RSA KMS 金鑰公有金鑰的原始 RSA keyring 來加密資料，則 AWS Encryption SDK 和 都 AWS KMS 無法解密它。您無法將 AWS KMS 非對稱 KMS 金鑰的私有金鑰匯出至原始 RSA keyring。 AWS KMS Decrypt 操作無法解密 AWS Encryption SDK 傳回的[加密訊息](concepts.md#message)。

在 中建構原始 RSA keyring 時 適用於 C 的 AWS Encryption SDK，請務必提供 PEM 檔案*的內容*，其中包含每個金鑰做為 null 終止的 C-string，而不是路徑或檔案名稱。在 JavaScript 中建構原始 RSA keyring 時，請注意與其他語言實作[的潛在不相容](javascript-compatibility.md)。

**命名空間和名稱**

為了識別 keyring 中的 RSA 金鑰材料，原始 RSA keyring 會使用您提供的*金鑰命名空間*和*金鑰名稱*。這些值並非機密。它們會以純文字顯示在加密操作傳回的[加密訊息](concepts.md#message)標頭中。我們建議您使用金鑰命名空間和金鑰名稱，以識別 HSM 或金鑰管理系統中的 RSA 金鑰對 （或其私有金鑰）。

**注意**  
金鑰命名空間和金鑰名稱等同於 和 中的*提供者 ID* （或*提供者*) `JceMasterKey`和*金鑰 ID* 欄位`RawMasterKey`。  
 適用於 C 的 AWS Encryption SDK 會保留 KMS `aws-kms`金鑰的金鑰命名空間值。請勿在原始 AES keyring 或原始 RSA keyring 中搭配 使用它 適用於 C 的 AWS Encryption SDK。

如果您建構不同的 keyring 來加密和解密指定的訊息，命名空間和名稱值至關重要。如果解密 keyring 中的金鑰命名空間和金鑰名稱不是加密 keyring 中金鑰命名空間和金鑰名稱的完全區分大小寫相符項目，即使金鑰來自相同的金鑰對，也不會使用解密 keyring。

無論 keyring 包含 RSA 公有金鑰、RSA 私有金鑰或金鑰對中的兩個金鑰，加密和解密 keyring 中金鑰材料的金鑰命名空間和金鑰名稱都必須相同。例如，假設您使用金鑰命名空間和金鑰`HSM_01`名稱 的 RSA 公有金鑰的原始 RSA keyring 來加密資料`RSA_2048_06`。若要解密該資料，請使用私有金鑰 （或金鑰對） 和相同的金鑰命名空間和名稱來建構原始 RSA keyring。

**填補模式**

您必須為用於加密和解密的原始 RSA keyring 指定填補模式，或使用您語言實作中為您指定的功能。

 AWS Encryption SDK 支援下列填補模式，受限於每種語言的限制。我們建議使用 [OAEP](https://tools.ietf.org/html/rfc8017#section-7.1) 填補模式，特別是使用 SHA-256 的 OAEP 和使用 SHA-256 填補的 MGF1。[PKCS1](https://tools.ietf.org/html/rfc8017#section-7.2) 填補模式僅支援回溯相容性。
+ 使用 SHA-1 的 OAEP 和使用 SHA-1 填補的 MGF1 SHA-1 
+ 使用 SHA-256 的 OAEP 和使用 SHA-256 填補的 MGF1 
+ OAEP 搭配 SHA-384 和 MGF1 搭配 SHA-384 填補
+ 使用 SHA-512 的 OAEP 和使用 SHA-512 填補的 MGF1 SHA-512 
+ PKCS1 v1.5 填補 

下列範例示範如何使用 RSA 金鑰對的公有和私有金鑰建立原始 RSA keyring，以及使用 SHA-256 建立 OAEP，並使用 SHA-256 填補模式建立 MGF1。`RSAPublicKey` 和 `RSAPrivateKey`變數代表您提供的金鑰材料。

------
#### [ C ]

若要在 中建立原始 RSA keyring 適用於 C 的 AWS Encryption SDK，請使用 `aws_cryptosdk_raw_rsa_keyring_new`。

在 中建構原始 RSA keyring 時 適用於 C 的 AWS Encryption SDK，請務必提供 PEM 檔案*的內容*，其中包含每個金鑰做為 null 終止的 C-string，而不是路徑或檔案名稱。如需完整範例，請參閱 [raw\_rsa\_keyring.c](https://github.com/aws/aws-encryption-sdk-c/blob/master/examples/raw_rsa_keyring.c)。

```
struct aws_allocator *alloc = aws_default_allocator();

AWS_STATIC_STRING_FROM_LITERAL(key_namespace, "HSM_01");
AWS_STATIC_STRING_FROM_LITERAL(key_name, "RSA_2048_06");

struct aws_cryptosdk_keyring *rawRsaKeyring = aws_cryptosdk_raw_rsa_keyring_new(
    alloc,
    key_namespace,
    key_name,
    private_key_from_pem,
    public_key_from_pem,
    AWS_CRYPTOSDK_RSA_OAEP_SHA256_MGF1);
```

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

若要在 AWS Encryption SDK 適用於 .NET 的 中執行個體化原始 RSA keyring，請使用 `materialProviders.CreateRawRsaKeyring()`方法。如需完整範例，請參閱 [RawRSAKeyringExample.cs](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/Examples/Keyring/RawRSAKeyringExample.cs)。

下列範例使用適用於 .NET 的 4 AWS Encryption SDK .*x* 版和更新版本。

```
// 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 = "RSA_2048_06";

// Get public and private keys from PEM files
var publicKey = new MemoryStream(System.IO.File.ReadAllBytes("RSAKeyringExamplePublicKey.pem"));
var privateKey = new MemoryStream(System.IO.File.ReadAllBytes("RSAKeyringExamplePrivateKey.pem"));

// Create the keyring input
var createRawRsaKeyringInput = new CreateRawRsaKeyringInput
{
    KeyNamespace = keyNamespace,
    KeyName = keyName,
    PaddingScheme = PaddingScheme.OAEP_SHA512_MGF1,
    PublicKey = publicKey,
    PrivateKey = privateKey
};

// Create the keyring
var rawRsaKeyring = materialProviders.CreateRawRsaKeyring(createRawRsaKeyringInput);
```

------
#### [ JavaScript Browser ]

瀏覽器 適用於 JavaScript 的 AWS Encryption SDK 中的 會從 [WebCrypto](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) 程式庫取得其密碼編譯基本程式碼。在建構 keyring 之前，您必須使用 `importPublicKey()`和/或 `importPrivateKey()` 將原始金鑰材料匯入 WebCrypto 後端。這可確保 keyring 是完整的，即使對 WebCrypto 的所有呼叫都是非同步的。匯入方法採取的物件包含包裝演算法及其填補模式。

匯入金鑰材料之後，請使用 `RawRsaKeyringWebCrypto()`方法來執行個體化 keyring。在 JavaScript 中建構原始 RSA keyring 時，請注意與其他語言實作[的潛在不相容](javascript-compatibility.md)。

下列範例使用 `buildClient`函數來指定[預設承諾政策](migrate-commitment-policy.md) `REQUIRE_ENCRYPT_REQUIRE_DECRYPT`。您也可以使用 `buildClient`來限制加密訊息中的加密資料金鑰數量。如需詳細資訊，請參閱[限制加密的資料金鑰](configure.md#config-limit-keys)。

如需完整範例，請參閱 [rsa\_simple.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/example-browser/src/rsa_simple.ts) (JavaScript 瀏覽器）。

```
import {
  RsaImportableKey,
  RawRsaKeyringWebCrypto,
  buildClient,
  CommitmentPolicy,
} from '@aws-crypto/client-browser'

const { encrypt, decrypt } = buildClient(
  CommitmentPolicy.{{REQUIRE_ENCRYPT_REQUIRE_DECRYPT}}
)

const privateKey = await RawRsaKeyringWebCrypto.importPrivateKey(
  privateRsaJwKKey
)

const publicKey = await RawRsaKeyringWebCrypto.importPublicKey(
  publicRsaJwKKey
)

const keyNamespace = '{{HSM_01}}'
const keyName = '{{RSA_2048_06}}'

const keyring = new RawRsaKeyringWebCrypto({
  keyName,
  keyNamespace,
  publicKey,
  privateKey,
})
```

------
#### [ JavaScript Node.js ]

若要在 適用於 JavaScript 的 AWS Encryption SDK for Node.js 中執行個體化原始 RSA keyring，請建立新的 `RawRsaKeyringNode`類別執行個體。`wrapKey` 參數會保留公有金鑰。`unwrapKey` 參數會保留私有金鑰。`RawRsaKeyringNode` 建構函數會為您計算預設填補模式，但您可以指定偏好的填補模式。

在 JavaScript 中建構原始 RSA keyring 時，請注意與其他語言實作[的潛在不相容](javascript-compatibility.md)。

下列範例使用 `buildClient`函數來指定[預設承諾政策](migrate-commitment-policy.md) `REQUIRE_ENCRYPT_REQUIRE_DECRYPT`。您也可以使用 `buildClient`來限制加密訊息中的加密資料金鑰數量。如需詳細資訊，請參閱[限制加密的資料金鑰](configure.md#config-limit-keys)。

如需完整範例，請參閱 [rsa\_simple.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/example-node/src/rsa_simple.ts) (JavaScript Node.js)。

```
import {
  RawRsaKeyringNode,
  buildClient,
  CommitmentPolicy,
} from '@aws-crypto/client-node'

const { encrypt, decrypt } = buildClient(
  CommitmentPolicy.{{REQUIRE_ENCRYPT_REQUIRE_DECRYPT}}
)

const keyNamespace = '{{HSM_01}}'
const keyName = '{{RSA_2048_06}}'

const keyring = new RawRsaKeyringNode({ keyName, keyNamespace, rsaPublicKey, rsaPrivateKey})
```

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

```
final CreateRawRsaKeyringInput keyringInput = CreateRawRsaKeyringInput.builder()
        .keyName("{{RSA_2048_06}}")
        .keyNamespace("{{HSM_01}}")
        .paddingScheme(PaddingScheme.{{OAEP_SHA256_MGF1}})
        .publicKey({{RSAPublicKey}})
        .privateKey({{RSAPrivateKey}})
        .build();
final MaterialProviders matProv = MaterialProviders.builder()
        .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
        .build();
IKeyring rawRsaKeyring = matProv.CreateRawRsaKeyring(keyringInput);
```

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

下列範例會使用[預設承諾政策](migrate-commitment-policy.md) 執行個體化 AWS Encryption SDK 用戶端`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`。如需完整範例，請參閱 GitHub 中 適用於 Python 的 AWS Encryption SDK 儲存庫中的 [raw\_rsa\_keyring\_example.py。](https://github.com/aws/aws-encryption-sdk-python/tree/master/examples/src/raw_rsa_keyring_example.py)

```
# Define the key namespace and key name
key_name_space = "{{HSM_01}}"
key_name = "{{RSA_2048_06}}"

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

# Create Raw RSA keyring
keyring_input: CreateRawRsaKeyringInput = CreateRawRsaKeyringInput(
    key_namespace=key_name_space,
    key_name=key_name,
    padding_scheme=PaddingScheme.{{OAEP_SHA256_MGF1}},
    public_key={{RSAPublicKey}},
    private_key={{RSAPrivateKey}}
)

raw_rsa_keyring: IKeyring = mat_prov.create_raw_rsa_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)?;

// 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()),
]);

// Define the key namespace and key name
let key_namespace: &str = "{{HSM_01}}";
let key_name: &str = "{{RSA_2048_06}}";
                    
// Instantiate the material providers library
let mpl_config = MaterialProvidersConfig::builder().build()?;
let mpl = mpl_client::Client::from_conf(mpl_config)?;

// Create Raw RSA keyring
let raw_rsa_keyring = mpl
    .create_raw_rsa_keyring()
    .key_name(key_name)
    .key_namespace(key_namespace)
    .padding_scheme(PaddingScheme::{{OaepSha256Mgf1}})
    .public_key(aws_smithy_types::Blob::new({{RSAPublicKey}}))
    .private_key(aws_smithy_types::Blob::new({{RSAPrivateKey}}))
    .send()
    .await?;
```

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

```
// Instantiate the material providers library
matProv, err := awscryptographymaterialproviderssmithygenerated.NewClient(awscryptographymaterialproviderssmithygeneratedtypes.MaterialProvidersConfig{})
                
// Create Raw RSA keyring
rsaKeyRingInput := awscryptographymaterialproviderssmithygeneratedtypes.CreateRawRsaKeyringInput{
	KeyName:       "rsa",
	KeyNamespace:  "rsa-keyring",
	PaddingScheme: awscryptographymaterialproviderssmithygeneratedtypes.PaddingSchemePkcs1,
	PublicKey:     pem.EncodeToMemory(publicKeyBlock),
	PrivateKey:    pem.EncodeToMemory(privateKeyBlock),
}

rsaKeyring, err := matProv.CreateRawRsaKeyring(context.Background(), rsaKeyRingInput)
```

------
#### [ 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 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",
}

// Define the key namespace and key name
var keyNamespace = "{{HSM_01}}"
var keyName = "{{RSA_2048_06}}"

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

// Create Raw RSA keyring
rsaKeyRingInput := mpltypes.CreateRawRsaKeyringInput{
    KeyName:       keyName,
    KeyNamespace:  keyNamespace,
    PaddingScheme: mpltypes.{{PaddingSchemeOaepSha512Mgf1}},
    PublicKey:     ({{RSAPublicKey}}),
    PrivateKey:    ({{RSAPrivateKey}}),
}
rsaKeyring, err := matProv.CreateRawRsaKeyring(context.Background(), rsaKeyRingInput)
if err != nil {
    panic(err)
}
```

------