RSA签名跨语言一致性及API验证失败技术求助
问题:RSA签名字符串一致但API验证失败,及签名重复性疑问
问题背景
我正在将C#代码改写为Python,其中包含一段用RSA算法对字符串签名后发送至API的逻辑。目前C#与Python生成的签名字符串完全一致,但目标API仅认可C#生成的签名,Python生成的签名验证失败。同时我有个疑问:使用RSA算法对同一字符串进行签名时,每次输出的签名是否相同?
依赖与核心代码
Python依赖与签名代码
from Cryptodome.Signature import pkcs1_15 from Cryptodome.Hash import SHA256 from Cryptodome.PublicKey import RSA import base64 ... key = RSA.import_key(open('rsa.private').read()) h = SHA256.new(normalize.encode('utf-8')) signature = pkcs1_15.new(key).sign(h) base64_bytes = base64.b64encode(signature) base64_signature = base64_bytes.decode('ascii') print(base64_signature)
C#核心签名代码
public static string SignData(String stringToBeSigned, string privateKey) { var pem = "-----BEGIN PRIVATE KEY----- " + privateKey + " -----END PRIVATE KEY-----"; PemReader pr = new PemReader(new StringReader(pem)); AsymmetricKeyParameter privateKeyParams = (AsymmetricKeyParameter)pr.ReadObject(); RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)privateKeyParams); RSACryptoServiceProvider csp = new RSACryptoServiceProvider(); csp.ImportParameters((RSAParameters)rsaParams); var dataBytes = Encoding.UTF8.GetBytes(stringToBeSigned); return Convert.ToBase64String(csp.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)); }
问题解答
1. 签名一致但API验证失败的排查方向
你认为签名字符串一致API就应通过验证的观点本身没问题,但需要排查以下隐性细节:
- 待签字符串的一致性:确认Python中的
normalize和C#中的stringToBeSigned是否完全一致,包括是否存在隐形字符、换行符差异,或字符串归一化逻辑(如空格处理、编码转换)的不同。 - 请求整体上下文匹配:API可能要求除签名外的其他参数(如时间戳、请求体格式、参数顺序)与C端完全一致,需检查Python请求的这些细节是否和C#对齐。
- Base64编码的隐性差异:虽然最终字符串一致,但要确认两端Base64编码是否遵循相同规则,比如是否保留填充字符
=、是否引入了不必要的换行符。
2. RSA签名的重复性问题
你当前使用的是RSA-PKCS1-v1_5签名方案(C#中RSASignaturePadding.Pkcs1、Python中pkcs1_15),这种方案是确定性的:对同一输入、同一私钥,每次生成的签名完全相同——因为签名过程是对数据哈希后用私钥加密,没有随机数参与。
只有当使用RSA-PSS签名方案时,由于引入了随机盐,每次签名结果才会不同。
内容的提问来源于stack exchange,提问作者Advaita
相关产品推荐
相关产品推荐

