首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在SHA256中验证RSA SHA256签名

在SHA256中验证RSA SHA256签名
EN

Stack Overflow用户
提问于 2019-10-31 10:09:45
回答 1查看 3.9K关注 0票数 0

我有一个签名和公钥,我想验证签名是否与我的输入数据相匹配。我甚至有一个Java示例,它可以工作,但不能将其转换为c#。

这就是我在C#上尝试过的,但没有任何效果。

代码语言:javascript
复制
string dataForSign = "456456" + "43223174" + "2016-11-28T14:57:50+0100" + "1148034147085158089";
string signature = "247A9B78E3FE5D4376B6A0DC2E6D721653E748F35473AFCD575FF8707CE6D8933E367B3D52E1EA6D2F2E22279F4EF5C144B48988352B02976D6CB864D947B02469DE7101A371FD4342E7C173F3C4C079B3E13B35D7FA60025A360A347D2A962B12BB3607E986CD32B149D4ADA87D94B4C4D632440066AFB8017527095420DFEC74C42D6D953FF292FB323FE59332ED81E7F227ACDDCC20AE54F9791F9A0C572ACB534278FD5850AB582E33D357448FE007702B6DB93C773DBB2349B00AF5D9FB116C70A70CF4EDCB95CD20D1D47705ADB7FBF38AF910289A128F08FFF2EB20C1BDF809D8D1EC9F0E3CAEBAE5593281ED50838807ED92B77B84F881B00490C56E";
string publicKey = "<RSAKeyValue><Modulus>MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA94CbbAspiut6qnC1iLzSJY4kmEgW/euPenOvMCB0EbbjSBVncx1Vi6UvbY86bu/3ZMgDBdhcq9fvqrdL2WLvacPWnHgIGCRV/8tlGs7oAcKei9V6OcyRjh0jD4TwBGqDUbQEfBXkLL1kJB8nPsLcUVrhmwGKM3qKTchSutpnDipRRSufswM2b8ScGLMX8O5J/54o85UiSP/ZZYcx4UDEpolN0k31Xa3fDw3tYn9KlIahALzgOqksF9jbv7jKS/DzpJAmQptuoL3t/0kj9J3tujh1NBpMoac7cCBiVCc+LVHga1Okn0R/1RotceYbkl6TaLW4O56XF5QorlHlkBWY5wID</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

byte[] dataForSignEncoded = Encoding.UTF8.GetBytes(dataForSign);
byte[] signatureEncoded = Convert.FromBase64String(signature);

RSACryptoServiceProvider rsaCryptoServiceProvider = new RSACryptoServiceProvider();
rsaCryptoServiceProvider.FromXmlString(publicKey);

var hashData = SHA256.Create().ComputeHash(dataForSignEncoded);
var result1 = rsaCryptoServiceProvider.VerifyHash(hashData, "SHA256", signatureEncoded);
var result2 = rsaCryptoServiceProvider.VerifyHash(hashData, signatureEncoded, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
var result3 = rsaCryptoServiceProvider.VerifyData(dataForSignEncoded, signatureEncoded, HashAlgorithmName.SHA256 ,RSASignaturePadding.Pkcs1);

以下是JAVA中的一个工作示例:

代码语言:javascript
复制
String dataForSign = "456456" + "43223174" + "2016-11-28T14:57:50+0100" + "1148034147085158089";
String signature = "247A9B78E3FE5D4376B6A0DC2E6D721653E748F35473AFCD575FF8707CE6D8933E367B3D52E1EA6D2F2E22279F4EF5C144B48988352B02976D6CB864D947B02469DE7101A371FD4342E7C173F3C4C079B3E13B35D7FA60025A360A347D2A962B12BB3607E986CD32B149D4ADA87D94B4C4D632440066AFB8017527095420DFEC74C42D6D953FF292FB323FE59332ED81E7F227ACDDCC20AE54F9791F9A0C572ACB534278FD5850AB582E33D357448FE007702B6DB93C773DBB2349B00AF5D9FB116C70A70CF4EDCB95CD20D1D47705ADB7FBF38AF910289A128F08FFF2EB20C1BDF809D8D1EC9F0E3CAEBAE5593281ED50838807ED92B77B84F881B00490C56E";
String publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA94CbbAspiut6qnC1iLzS\n"
                + "JY4kmEgW/euPenOvMCB0EbbjSBVncx1Vi6UvbY86bu/3ZMgDBdhcq9fvqrdL2WLv\n"
                + "acPWnHgIGCRV/8tlGs7oAcKei9V6OcyRjh0jD4TwBGqDUbQEfBXkLL1kJB8nPsLc\n"
                + "UVrhmwGKM3qKTchSutpnDipRRSufswM2b8ScGLMX8O5J/54o85UiSP/ZZYcx4UDE\n"
                + "polN0k31Xa3fDw3tYn9KlIahALzgOqksF9jbv7jKS/DzpJAmQptuoL3t/0kj9J3t\n"
                + "ujh1NBpMoac7cCBiVCc+LVHga1Okn0R/1RotceYbkl6TaLW4O56XF5QorlHlkBWY\n"
                + "5wIDAQAB";

byte[] publicKeyEncoded = DatatypeConverter.parseBase64Binary(publicKey);
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(publicKeyEncoded);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pk = kf.generatePublic(pubKeySpec);

Signature rsa = Signature.getInstance("SHA256withRSA");
rsa.initVerify(pk);
rsa.update(dataForSign.getBytes("UTF-8"));
boolean result = rsa.verify(StringUtil.tobin(signature)); // convert hex signature to bytes
System.out.println(result);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-31 12:19:20

两件事;

  • 签名不是base64编码的,它是一个十六进制字符串,所以您比较的是错误的签名。一种正确的转换方法,例如,可以找到here;

代码语言:javascript
复制
public static byte[] StringToByteArray(string hex)
{
    return Enumerable.Range(0, hex.Length)
        .Where(x => x % 2 == 0)
        .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
        .ToArray();
}

  • 您似乎将您的RSA密钥错误地编码成XML,这也给您带来了不匹配。

纠正这两件事;

代码语言:javascript
复制
string dataForSign = "456456" + "43223174" + "2016-11-28T14:57:50+0100" + "1148034147085158089";
string signature = "247A9B78E3FE5D4376B6A0DC2E6D721653E748F35473AFCD575FF8707CE6D8933E367B3D52E1EA6D2F2E22279F4EF5C144B48988352B02976D6CB864D947B02469DE7101A371FD4342E7C173F3C4C079B3E13B35D7FA60025A360A347D2A962B12BB3607E986CD32B149D4ADA87D94B4C4D632440066AFB8017527095420DFEC74C42D6D953FF292FB323FE59332ED81E7F227ACDDCC20AE54F9791F9A0C572ACB534278FD5850AB582E33D357448FE007702B6DB93C773DBB2349B00AF5D9FB116C70A70CF4EDCB95CD20D1D47705ADB7FBF38AF910289A128F08FFF2EB20C1BDF809D8D1EC9F0E3CAEBAE5593281ED50838807ED92B77B84F881B00490C56E";
string publicKey =
    "<RSAKeyValue><Modulus>94CbbAspiut6qnC1iLzSJY4kmEgW/euPenOvMCB0EbbjSBVncx1Vi6UvbY86bu/3ZMgDBdhcq9fvqrdL2WLvacPWnHgIGCRV/8tlGs7oAcKei9V6OcyRjh0jD4TwBGqDUbQEfBXkLL1kJB8nPsLcUVrhmwGKM3qKTchSutpnDipRRSufswM2b8ScGLMX8O5J/54o85UiSP/ZZYcx4UDEpolN0k31Xa3fDw3tYn9KlIahALzgOqksF9jbv7jKS/DzpJAmQptuoL3t/0kj9J3tujh1NBpMoac7cCBiVCc+LVHga1Okn0R/1RotceYbkl6TaLW4O56XF5QorlHlkBWY5w==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

byte[] dataForSignAsBytes = Encoding.UTF8.GetBytes(dataForSign);
byte[] signatureAsBytes = StringToByteArray(signature);

RSACryptoServiceProvider rsaCryptoServiceProvider = new RSACryptoServiceProvider();
rsaCryptoServiceProvider.FromXmlString(publicKey);

var hashData = SHA256.Create().ComputeHash(dataForSignAsBytes);

var result1 = rsaCryptoServiceProvider.VerifyData(dataForSignAsBytes, CryptoConfig.MapNameToOID("SHA256"), signatureAsBytes);
var result2 = rsaCryptoServiceProvider.VerifyHash(hashData, CryptoConfig.MapNameToOID("SHA256"), signatureAsBytes);
var result3 = rsaCryptoServiceProvider.VerifyHash(hashData, signatureAsBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
var result4 = rsaCryptoServiceProvider.VerifyData(dataForSignAsBytes, signatureAsBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
Console.WriteLine(result1);
Console.WriteLine(result2);
Console.WriteLine(result3);
Console.WriteLine(result4);

...gives真/真。

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

https://stackoverflow.com/questions/58640961

复制
相关文章

相似问题

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