首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RSA-RSA 256签名不匹配

RSA-RSA 256签名不匹配
EN

Stack Overflow用户
提问于 2021-01-07 09:16:07
回答 1查看 810关注 0票数 0

我正致力于EWP (Erasmus无论文)的实现,这是一组API,用于在世界各地的大学之间进行通信。每个呼叫都必须用RSA-RSA 256签名。每个合作伙伴都有一个私钥和公钥,公钥在带有keyId的注册表中是可用的。请求有一些标题:主体摘要(sha256散列)、主机、日期、x请求id(随机guid)。这些标头及其值以签名字符串连接在一起,该字符串与私钥签名,其结果是在标头中也发送的签名,以及用于签名的keyId和其他标头。服务器需要检查签名是否有效,方法是创建相同的签名字符串,在注册表中查找公钥,然后检查请求中的签名是否确实正确。

我有两个API作为客户端应用程序来进行测试。我可以访问109个不同的合作伙伴进行测试,其中一些还没有准备好(它们在我的客户端和在线验证器中都显示了一个错误,所以我假设那个API服务器端有一个错误,因为它是一个开发环境),另外一些还可以正常工作。还有EWP的测试API,还有一个在线验证器,您可以使用它向这些API中的任何一个发送请求。

奇怪的是,我的客户端与几乎所有的合作伙伴API一起工作,而其中一些API给了我一个错误--我的签名是错误的(当在线验证器正常工作时)。在我自己的API上使用我的客户端,验证工作正常。使用联机验证程序,我的验证不起作用(无效签名错误)。有两个合作伙伴我的客户不工作,在线验证器工作,和3个API的地方,我的客户端工作,但在线验证器没有(包括我自己的API)

有人能想到什么会引起这些问题吗?奇怪的是,两周前,在线验证器确实在我的API上工作,根据EWP的说法,唯一改变的是在线验证器使用的密钥对,但他声称我现在使用的是正确的(我给他发送了日志)。

会不会是某种字符集的问题?只有当某个字符被用于公钥或类似的东西时,才会发生错误?

这是我的RSA- the 256部分的代码:

在客户端请求中使用私钥:创建签名

代码语言:javascript
复制
public string CreateSignature(string SigningString)
{
    byte[] message = Encoding.UTF8.GetBytes(SigningString);
    PemReader pr = new PemReader(new StringReader(privateKeyString));
    AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pr.ReadObject();

    RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)keyPair.Private);
    RSACng rsaCng = new RSACng();
    rsaCng.ImportParameters(rsaParams);
    byte[] signatureBytes = rsaCng.SignData(message, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

    return Convert.ToBase64String(signatureBytes);
}

检查接收到的签名是否正确:

代码语言:javascript
复制
public bool IsRsaHashCorrect(string originalMessage, string hash, string stringPublicKey)
{
    string x509Pem = @"-----BEGIN PUBLIC KEY-----" + stringPublicKey + "-----END PUBLIC KEY-----";

    byte[] message = Encoding.UTF8.GetBytes(originalMessage);
    byte[] signature = Convert.FromBase64String(hash);

    byte[] Sha256Message = SHA256.Create().ComputeHash(message);

    PemReader pr = new PemReader(new StringReader(x509Pem));
    AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject();

    RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey);
    RSACng rsaCng = new RSACng();
    rsaCng.ImportParameters(rsaParams);

    var result = rsaCng.VerifyHash(Sha256Message, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

    log.Info("check rsa-sha256 hash: " + result);

    return result;
}

因此,长话短说:以上代码有时运行良好,有时失败。为什么?为什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-07 17:56:10

问题解决了!结果,请求标头中日期的格式出现了问题。签名字符串中也使用此日期。不同的日期格式意味着无效签名。

在线验证器发出的请求的日期是清华,2021年1月7日14:01:58格林尼治标准时间,在我的代码中获取这个日期时,它被转换为清华,01月7日14:01:58格林尼治时间(当天领先0)。

代码语言:javascript
复制
requestContext.Date = request.Headers.GetValues("date").Last();

现在,当第一次验证失败时,我再次尝试删除前导零的更改日期。只有在失败的情况下,签名验证才会失败。原来其他的合作伙伴也在约会中使用领先的零值,这就是为什么我的客户确实使用了一些API而不是其他的.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65609565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档