2

我正在尝试加快速度,了解如何获取一些使用 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对象
  • 接收消息和它的签名
  • 尝试验证签名

我已经完成了前两部分(我已经验证了公钥是否正确加载,因为我设法将 RSA 加密文本从 C# 代码发送到 C 中的 OpenSSL 代码并成功解密)

为了验证 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!
4

2 回答 2

1

如果您展示了您的 C# 代码,它可能会有所帮助。我认为它应该是这样的:

    string msg = ...;
    byte[] localData = Encoding.UTF8.GetBytes(msg);
    bool ok = rsa.VerifyHash(localData, "SHA1", receivedhash);

当然,我只是在猜测 UTF-8 部分。也可能是ASCII。

编辑:这是MSDN 页面。该示例似乎有所不同,首先对 localData 进行哈希处理。

hashedData = hash.ComputeHash(signedData);
return rsaCSP.VerifyHash(hashedData, CryptoConfig.MapNameToOID("SHA1"), signature);
于 2010-05-11T16:02:12.837 回答
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 文件阅读器代码。

于 2011-06-05T12:59:25.083 回答