使用C#调用AWS KMS非对称密钥加解密报错求助
AWS Encryption SDK .NET 非对称KMS密钥加解密错误修复
使用AWS Encryption SDK的.NET SDK进行KMS加解密时,对称密钥可以正常运行,但切换为非对称密钥后抛出错误:
You cannot generate a data key with an asymmetric CMK
问题原因
AWS Encryption SDK默认的KMS Keyring会尝试生成数据密钥(Data Key),但非对称CMK不支持生成数据密钥的操作,必须使用专门的非对称Keyring,直接通过公钥加密、私钥解密完成操作。
修改后的完整代码
using AWS.EncryptionSDK.Core; using AWS.EncryptionSDK; using Amazon.KeyManagementService; using Amazon.KeyManagementService.Model; using System.Text; public static class EncryptionHelper { private const string aliasName = "myAliasName"; public static MemoryStream EncryptData(string data) { var materialProviders = AwsCryptographicMaterialProvidersFactory.CreateDefaultAwsCryptographicMaterialProviders(); var encryptionSdk = AwsEncryptionSdkFactory.CreateDefaultAwsEncryptionSdk(); // 创建非对称KMS Keyring输入(加密时使用公钥) var asymmetricKeyringInput = new CreateAwsKmsAsymmetricMrkKeyringInput { KmsClient = new AmazonKeyManagementServiceClient(), KmsKeyId = GetARNBasedOnAliasName(), // 指定与KMS密钥匹配的非对称加密算法 EncryptionAlgorithm = EncryptionAlgorithmSpec.RSAES_OAEP_SHA_256 }; var keyring = materialProviders.CreateAwsKmsAsymmetricMrkKeyring(asymmetricKeyringInput); var dataStream = StringToMemoryStream(data); var encryptInput = new EncryptInput { Keyring = keyring, Plaintext = dataStream }; var result = encryptionSdk.Encrypt(encryptInput); return result.Ciphertext; } public static MemoryStream DecryptData(MemoryStream ciphertext) { var materialProviders = AwsCryptographicMaterialProvidersFactory.CreateDefaultAwsCryptographicMaterialProviders(); var encryptionSdk = AwsEncryptionSdkFactory.CreateDefaultAwsEncryptionSdk(); // 创建非对称KMS Keyring输入(解密时使用私钥) var asymmetricKeyringInput = new CreateAwsKmsAsymmetricMrkKeyringInput { KmsClient = new AmazonKeyManagementServiceClient(), KmsKeyId = GetARNBasedOnAliasName(), // 解密时SDK可自动匹配算法,也可显式指定 EncryptionAlgorithm = EncryptionAlgorithmSpec.RSAES_OAEP_SHA_256 }; var keyring = materialProviders.CreateAwsKmsAsymmetricMrkKeyring(asymmetricKeyringInput); var decryptInput = new DecryptInput { Ciphertext = ciphertext, Keyring = keyring }; var res = encryptionSdk.Decrypt(decryptInput); return res.Plaintext; } public static string GetARNBasedOnAliasName() { using var client = new AmazonKeyManagementServiceClient(); var describeKeyRequest = new DescribeKeyRequest { KeyId = aliasName }; var describeKeyResponse = client.DescribeKeyAsync(describeKeyRequest).Result; return describeKeyResponse.KeyMetadata.Arn; } public static MemoryStream StringToMemoryStream(string str) { var dataBytes = Encoding.UTF8.GetBytes(str); return new MemoryStream(dataBytes); } public static string MemoryStreamToString(MemoryStream response) { return Encoding.UTF8.GetString(response.ToArray()); } }
关键修改点
- 替换默认的
CreateAwsKmsKeyringInput为CreateAwsKmsAsymmetricMrkKeyringInput,这是AWS SDK提供的专门用于非对称KMS密钥的Keyring类型 - 显式指定
EncryptionAlgorithm,需与你的KMS非对称密钥算法一致(例如RSA密钥对应RSAES_OAEP_SHA_256,ECC密钥对应对应的ECC加密算法) - 解密方法调整为直接接收
MemoryStream类型的密文,避免二进制密文转字符串再转回流导致的数据损坏
注意事项
- 非对称KMS密钥有明文大小限制,例如RSAES-OAEP算法的最大明文长度为密钥长度(字节)减42,2048位密钥最多加密214字节数据
- 确保IAM权限允许使用目标非对称密钥的
Encrypt和Decrypt操作(对称密钥对应的是GenerateDataKey权限)
内容的提问来源于stack exchange,提问作者Rousonur Jaman
相关产品推荐
相关产品推荐

