AWS Encryption CLI/Python SDK解密失败,Java SDK正常问题排查
问题描述
我们已通过AWS Encryption SDK for Java实现数据库单个字段的加密/解密功能,使用AWS KMS密钥完成该任务,运行正常。现在需通过Python工具脚本访问解密后的数据,编写的示例代码如下:
def decrypt_string(key_arn, ciphertext, botocore_session=None): # 设置加密客户端并指定承诺策略,默认即为REQUIRE_ENCRYPT_REQUIRE_DECRYPT client = aws_encryption_sdk.EncryptionSDKClient(commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT) # 创建AWS KMS主密钥提供器 kms_kwargs = dict(key_ids=[key_arn]) if botocore_session is not None: kms_kwargs["botocore_session"] = botocore_session master_key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(**kms_kwargs) # 解密密文 plaintext, decrypted_header = client.decrypt(source=ciphertext, key_provider=master_key_provider) print(plaintext)
Java与Python实现的承诺策略一致,但使用相同密钥ARN和原始密文调用该函数时,出现以下错误:
aws_encryption_sdk.exceptions.NotSupportedError: Unsupported signing algorithm info
我们尝试用AWS Encryption CLI解密同一密文,命令如下:
echo '<base64-encoded cipher text>' | \ aws-encryption-cli \ --decrypt \ --decode \ --wrapping-keys key=<KMS KEY ARN> \ --commitment-policy require-encrypt-require-decrypt \ -S \ --input - \ --output -
但仍报相同错误。随后用AWS Encryption CLI加密示例文本,依旧触发该错误。
KMS密钥元数据如下:
{ "KeyMetadata": { "AWSAccountId": "<account-id>", "KeyId": "<key-id>", "Arn": "arn:aws:kms:eu-central-1:<account-id>:key/<key-id>", "CreationDate": "2023-06-07T10:35:18.466000+02:00", "Enabled": true, "Description": "", "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "Enabled", "Origin": "AWS_KMS", "KeyManager": "CUSTOMER", "CustomerMasterKeySpec": "SYMMETRIC_DEFAULT", "KeySpec": "SYMMETRIC_DEFAULT", "EncryptionAlgorithms": [ "SYMMETRIC_DEFAULT" ], "MultiRegion": false } }
使用的软件版本:
- Python依赖版本:
- aws-encryption-sdk: 3.1.1
- aws-encryption-sdk-cli: 4.1.0
- boto3: 1.26.148
- Java依赖版本:
- org.bouncycastle.bcprov-ext-jdk18on: 1.73
- com.amazonaws.aws-encryption-sdk-java: 2.4.0
请问是密钥创建不当,还是存在其他遗漏配置?
问题分析与解决方案
这个错误的核心原因是Java SDK 2.4.0与Python SDK 3.x版本之间的签名算法默认值不兼容,和密钥本身无关:
- Java SDK 2.4.0默认使用
SHA-256作为签名算法 - Python SDK 3.x版本在启用
REQUIRE_ENCRYPT_REQUIRE_DECRYPT承诺策略时,默认要求SHA-384签名算法
两者签名算法不匹配,就会触发Unsupported signing algorithm info错误。
修复方案
方案1:修改Python代码,兼容Java的签名算法
在创建加密客户端时,显式指定签名算法为SHA256:
from aws_encryption_sdk.identifiers import CommitmentPolicy, SignatureAlgorithm def decrypt_string(key_arn, ciphertext, botocore_session=None): # 显式指定签名算法为SHA256,匹配Java SDK默认值 client = aws_encryption_sdk.EncryptionSDKClient( commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT, preferred_signature_algorithm=SignatureAlgorithm.SHA256 ) kms_kwargs = dict(key_ids=[key_arn]) if botocore_session is not None: kms_kwargs["botocore_session"] = botocore_session master_key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(**kms_kwargs) plaintext, decrypted_header = client.decrypt(source=ciphertext, key_provider=master_key_provider) print(plaintext)
方案2:修改Java代码,对齐Python的默认签名算法
如果后续希望统一使用Python的配置,可以在Java加密时显式指定SHA-384:
// 创建加密客户端时指定签名算法 EncryptionSdk encryptionSdk = EncryptionSdk.builder() .commitmentPolicy(CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT) .preferredSignatureAlgorithm(SignatureAlgorithm.SHA_384) .build();
CLI解密的修复方式
使用CLI时,需要添加--signature-algorithm参数指定SHA256:
echo '<base64-encoded cipher text>' | \ aws-encryption-cli \ --decrypt \ --decode \ --wrapping-keys key=<KMS KEY ARN> \ --commitment-policy require-encrypt-require-decrypt \ --signature-algorithm SHA256 \ -S \ --input - \ --output -
内容的提问来源于stack exchange,提问作者Kees de Bruin
相关产品推荐
相关产品推荐

