我正在努力加快如何使用OpenSSL进行加密的一些代码,使用.NET中提供的Microsoft加密提供程序,与我用C#编写的另一个程序一起玩。
更重要的是,我正在尝试让C#程序验证OpenSSL代码生成的RSA消息签名。生成签名的代码如下所示:
// Code in C, using the OpenSSL RSA implementation
char msgToSign[] = "Hello World"; // the message to be signed
char signature[RSA_size(rsa)]; // buffer that will hold signature
int slen = 0; // will contain signature size
// rsa is an OpenSSL RSA context, that's loaded with the public/private key pair
memset(signature, 0, sizeof(signature));
RSA_sign(NID_sha1
, (unsigned char*)msgToSign
, strlen(msgToSign)
, signature
, &slen
, rsa);
// now signature contains the message signature
// and can be verified using the RSA_verify counterpart
// .. I would like to verify the signature in C#
在C#中,我会做以下事情:
RSACryptoServiceProvider
对象我有前两部分工作(我已经验证公钥正确加载,因为我设法将C#代码中的RSA加密文本发送到C中的OpenSSL代码并成功解密)< / p>
为了验证C#中的签名,我尝试使用RSACryptoServiceProvider的:VerifySignature方法,但是没有用。在互联网上挖掘我只能找到一些模糊的信息,指出.NET使用不同的方法生成签名而不是OpenSSL。那么,有人知道如何做到这一点吗?
修改
由于有请求,这里是C#方面的事情..
byte[] receivedSignature;
// ....
// receivedSignature is set to the byte array generated by the OpenSSL side
// I've verified this much is working correctly
// I use my utility to parse a PEM file and extract the other side's public key
// also, verified to be working correctly - the public key is good.
RSACryptoServiceProvider rsa = MyPEMLoader.LoadFromFile("publicKey.pem");
string msgToVerify = "Hello World";
byte[] msgBytes = Encoding.ASCII.GetBytes(msg); // other side uses ASCII, so do the same
bool verified = rsa.VerifyHash(msgBytes, "SHA1", receivedSignature);
// verfied is false.. verfification failed!
答案 0 :(得分:1)
如果您展示了C#代码,可能会有所帮助。我认为它应该是这样的:
<击> 撞击>
<击> string msg = ...;
byte[] localData = Encoding.UTF8.GetBytes(msg);
bool ok = rsa.VerifyHash(localData, "SHA1", receivedhash);
当然,我只是在猜测UTF-8部分。也可能是ASCII。
击><击> 撞击>
编辑:这是MSDN page。这个例子看起来有所不同,localData首先进行哈希处理。
hashedData = hash.ComputeHash(signedData);
return rsaCSP.VerifyHash(hashedData, CryptoConfig.MapNameToOID("SHA1"), signature);
答案 1 :(得分:0)
您应该删除您的pem实用程序,这不是必需的,请使用
var cert = new X509Certificate2(HttpContext.Current.Request.MapPath("~/App_Data/PublicKey.pem"), "");
var rsaCryptoIPT = (RSACryptoServiceProvider)cert.PublicKey.Key;
var sha1 = new SHA1CryptoServiceProvider();
if (!rsaCryptoIPT.VerifyData(data, sha1, signature))
throw new InvalidOperationException("Invalid signature from bank ");
如果这没有帮助,你可以发布pem文件阅读器代码。