Go AWS KMS SDK返回签名本地验证失败问题咨询
问题分析与解决方案
你的base64.StdEncoding.EncodeToString(signResp.Signature)转换本身是正确的,但问题出在KMS签名的格式兼容性上,以下是具体原因和解决办法:
核心原因
AWS KMS的Sign API返回的签名(无论是SDK字节切片还是CLI的Base64解码后),默认是ASN.1 DER编码格式(包含哈希算法OID等元数据);而openssl dgst -verify命令默认期望的是原始PKCS#1格式的签名(仅包含签名字节,无ASN.1包装)。这就是本地验证失败的核心矛盾。
解决方案
方案1:调整OpenSSL命令适配DER格式签名
无需修改Go代码,直接给dgst命令添加参数或用rsautl工具处理DER签名:
- 若使用RSA密钥+PSS填充(KMS默认RSA签名算法):
openssl dgst -SHA256 -verify pubkey.pem -signature signature.bin -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 data.txt
- 通用解析方式(先提取原始PKCS#1签名):
# 从DER签名中提取原始PKCS#1字节 openssl rsautl -verify -inkey pubkey.pem -pubin -in signature.bin -out raw_signature.bin -asn1parse # 用原始签名验证数据 openssl dgst -SHA256 -verify pubkey.pem -signature raw_signature.bin data.txt
方案2:在Go代码中转换为PKCS#1格式
如果希望本地直接用默认的openssl dgst -verify命令验证,可以在Lambda中解析KMS返回的DER签名,提取原始PKCS#1签名字节后再转Base64:
import ( "encoding/asn1" "encoding/base64" ) // 定义ASN.1签名结构 type asn1Signature struct { Algorithm asn1.ObjectIdentifier Signature []byte } // 处理KMS签名,转换为PKCS#1格式的Base64字符串 func processKmsSignature(signature []byte) (string, error) { var sig asn1Signature _, err := asn1.Unmarshal(signature, &sig) if err != nil { return "", err } return base64.StdEncoding.EncodeToString(sig.Signature), nil } // 在你的签名逻辑中调用 encodedSignature, err := processKmsSignature(signResp.Signature)
额外排查点
- 哈希算法一致性:确认Lambda中调用KMS Sign时指定的签名算法(如
SigningAlgorithmRSASSA_PSS_SHA_256)和OpenSSL命令中的-SHA256完全匹配。 - 原始数据一致性:Lambda中签名的原始数据和本地
data.txt的内容必须完全一致(包括换行符、编码、末尾空格等,建议用二进制对比工具验证)。 - Base64完整性:确保Lambda返回的Base64字符串没有被截断或添加额外字符(如API Gateway自动插入的换行),本地保存
signature.txt时不要手动修改内容。
内容的提问来源于stack exchange,提问作者Chris Shepherd
相关产品推荐
相关产品推荐

