原始 RSA keyring - AWS Encryption SDK

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

原始 RSA keyring

原始 RSA keyring 會使用您提供的 RSA 公有和私有金鑰,對本機記憶體中的資料金鑰執行非對稱加密和解密。您需要產生、存放和保護私有金鑰,最好是在硬體安全模組 (HSM) 或金鑰管理系統中。加密函數會根據 RSA 公開金鑰加密資料金鑰。解密函數會使用私有金鑰解密資料金鑰。您可以從數個 RSA 填補模式中選擇。

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

Raw RSA keyring 等同於 中的 JceMasterKey 和 中的 適用於 JAVA 的 AWS Encryption SDK RawMasterKey,並在與 RSA 非對稱加密金鑰搭配使用 適用於 Python 的 AWS Encryption SDK 時與其相互操作。您可以使用一個實作來加密資料,並利用使用相同包裝金鑰的任何其他實作來解密資料。如需詳細資訊,請參閱Keyring 相容性

注意

原始 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,與選用的密碼編譯材料提供者程式庫 (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 傳回的加密訊息

在 中建構原始 RSA keyring 時 適用於 C 的 AWS Encryption SDK,請務必提供 PEM 檔案的內容,其中包含每個金鑰做為 null 終止的 C 字串,而不是路徑或檔案名稱。在 JavaScript 中建構原始 RSA keyring 時,請注意與其他語言實作的潛在不相容

命名空間和名稱

為了識別 keyring 中的 RSA 金鑰材料,原始 RSA keyring 會使用您提供的金鑰命名空間金鑰名稱。這些值並非機密。它們會以純文字顯示在加密操作傳回的加密訊息標頭中。我們建議您使用金鑰命名空間和金鑰名稱,以識別 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 填補模式,特別是使用 SHA-256 的 OAEP 和使用 SHA-256 填補的 MGF1。PKCS1 填補模式僅支援回溯相容性。

  • 使用 SHA-1 的 OAEP 和使用 SHA-1 填補的 MGF1 SHA-1

  • OAEP 搭配 SHA-256 和 MGF1 搭配 SHA-256 填補

  • 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。RSAPublicKeyRSAPrivateKey變數代表您提供的金鑰材料。

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

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

下列範例使用適用於 .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 程式庫取得其密碼編譯基本程式碼。在建構 keyring 之前,您必須使用 importPublicKey()和/或 importPrivateKey() 將原始金鑰材料匯入 WebCrypto 後端。這可確保即使對 WebCrypto 的所有呼叫都是非同步的, keyring 也是完整的。匯入方法採取的物件包含包裝演算法及其填補模式。

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

下列範例使用 buildClient函數來指定預設承諾政策 REQUIRE_ENCRYPT_REQUIRE_DECRYPT。您也可以使用 buildClient來限制加密訊息中的加密資料金鑰數量。如需詳細資訊,請參閱限制加密的資料金鑰

如需完整範例,請參閱 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 時,請注意與其他語言實作的潛在不相容

下列範例使用 buildClient函數來指定預設承諾政策 REQUIRE_ENCRYPT_REQUIRE_DECRYPT。您也可以使用 buildClient來限制加密訊息中的加密資料金鑰數量。如需詳細資訊,請參閱限制加密的資料金鑰

如需完整範例,請參閱 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

下列範例會使用預設承諾政策 執行個體化 AWS Encryption SDK 用戶端REQUIRE_ENCRYPT_REQUIRE_DECRYPT。如需完整範例,請參閱 GitHub 中 適用於 Python 的 AWS Encryption SDK 儲存庫中的 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) }