如何将openssl_pkey_get_public和openssl_verify转换为C#.NET

时间:2011-06-04 17:20:32

标签: c# asp.net security cryptography openssl

PHP代码验证来自银行的iPizza签名:

$key = openssl_pkey_get_public (file_get_contents ($preferences['bank_certificate'])); 
if (!openssl_verify ($data, $signature, $key)) { 
    trigger_error ("Invalid signature", E_USER_ERROR); 
    } 

我尝试使用

将其转换为ASP .NET
SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
X509Certificate2 cert = new X509Certificate2(HttpContext.Current.Request.MapPath("~/App_Data/bankert.crt"), "");
RSACryptoServiceProvider rsaCryptoIPT = new RSACryptoServiceProvider();
rsaCryptoIPT.ImportCspBlob(cert.RawData);
if (!rsaCryptoIPT.VerifyData(data, CryptoConfig.MapNameToOID("SHA1"), signature))
    throw new InvalidOperationException("Invalid signature from bank ");

但是行rsaCryptoIPT.ImportCspBlob(cert.RawData)会导致Cryptography.CryptographicException无效的提供程序版本:

  StackTrace:
       at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
       at System.Security.Cryptography.Utils._ImportCspBlob(Byte[] keyBlob, SafeProvHandle hProv, CspProviderFlags flags, SafeKeyHandle& hKey)
       at System.Security.Cryptography.Utils.ImportCspBlobHelper(CspAlgorithmType keyType, Byte[] keyBlob, Boolean publicOnly, CspParameters& parameters, Boolean randomKeyContainer, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle)
       at System.Security.Cryptography.RSACryptoServiceProvider.ImportCspBlob(Byte[] keyBlob)
...

如何解决?

bank_certificate文件包含

  

----- BEGIN CERTIFICATE ----- MIIDRTCCAq6gAwIBAgIBADANBgkqhkiG9w0BAQQFADB7MQswCQYDVQQGEwJFRTEO   ....   C82uR / wUZJDw9kj + R1O46 / byG8yA + S9FVw ==   -----结束证书-----

更新:我根据对

的专横答案更改了代码
var cert = new X509Certificate2(HttpContext.Current.Request.MapPath("~/App_Data/banksert.crt"), "");
var rsaCryptoIPT = (RSACryptoServiceProvider)cert.PublicKey.Key;
var sha1 = new SHA1CryptoServiceProvider();
if (!rsaCryptoIPT.VerifyData(data, sha1, signature))
  throw new InvalidOperationException("Invalid signature from bank ");

此代码导致银行异常的无效签名。在show cert数据中检查cert对象。 如何解决这个问题,以便验证签名? 调试器显示银行证书有效日期已过期。可能这会导致错误或VerifyDate第二个参数错误。

我可以使用代码

成功签署数据,银行接受签名
SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
X509Certificate2 cert = new X509Certificate2(HttpContext.Current.Request.MapPath("~/App_Data/P12File.p12"), "");
RSACryptoServiceProvider rsaCryptoIPT = (RSACryptoServiceProvider)cert.PrivateKey;
byte[] binSignature = rsaCryptoIPT.SignData(binData, sha1);

验证银行签名应该与此过程相反,使用相同的算法。如何验证签名?

2 个答案:

答案 0 :(得分:1)

您是否安装了增强型加密提供程序? 实际上,为了不依赖于加密提供程序,您可以使用其他库,这些库在本机代码中实现所有加密内容。我知道EldoS SecureBlackbox(商用)和Bouncy Castle(免费),但市场上可以有其他库。

答案 1 :(得分:1)

如果X509Certificate2已成功导入证书文件,那么您将从PublicKey.Key参数获取证书的公钥。