SHA256签名

时间:2012-05-20 11:50:13

标签: rsa sha1 signature sha256 rsacryptoserviceprovider

我有一张智能卡,我需要用这个来签名。 这是我在stackover中看到的一个大问题。

我无法使用RSACryptoServiceProvider,bkz它不支持RSA-SHA256算法。

首先,我使用了CAPICOM.dll,如下面的代码,

SignedData sed = new SignedData();
sed.Content = "a"; // data to sign
Signer ser = new Signer();
ser.Certificate = cc;
string singnn = sed.Sign(ser, false, CAPICOM_ENCODING_TYPE.CAPICOM_ENCODE_BASE64);

但是没有公钥来验证我的签名值,我无法从capicom.dll获取验证密钥。

之后,

我使用X509Certificate2和RSACryptoServiceProvider,如下面的代码,

        X509Certificate2 certificate = new X509Certificate2();
        // Access Personal (MY) certificate store of current user
        X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        my.Open(OpenFlags.ReadOnly);

        // Find the certificate we'll use to sign            
        RSACryptoServiceProvider csp = null;
        foreach (X509Certificate2 cert in my.Certificates)
        {
            if (cert.Subject.Contains(certSubject))
            {
                // We found it. 
                // Get its associated CSP and private key
                certificate = cert;
                csp = (RSACryptoServiceProvider)cert.PrivateKey;
            }
        }
        if (csp == null)
        {
            throw new Exception("No valid cert was found");
        }

        // Hash the data
        SHA1Managed sha1 = new SHA1Managed();
        UnicodeEncoding encoding = new UnicodeEncoding();
        byte[] data = encoding.GetBytes(text);
        byte[] hash = sha1.ComputeHash(data);

        //byte[] data = Encoding.UTF8.GetBytes(text);
        //HashAlgorithm sha = new SHA256Managed();
        //byte[] hash = sha.TransformFinalBlock(data, 0, data.Length);

        string key = csp.ToXmlString(false);
        // Sign the hash
        csp.PersistKeyInCsp = true;
        byte[] response = csp.SignData(data, CryptoConfig.MapNameToOID("SHA1"));
        string signbase64 = Convert.ToBase64String(response);

它有效,但我需要使用RSA-SHA256算法进行签名。 当我像这样改变哈希算法时

byte[] response = csp.SignData(data, CryptoConfig.MapNameToOID("SHA256"));

我得到了

  

错误:“未指定的错误”。

多数民众赞成我的问题, 什么是溶剂,或者我应该使用哪个库?

感谢您的任何建议..

1 个答案:

答案 0 :(得分:13)

RSACryptoServiceProvider可以使用基于SHA2的签名,但您必须投入一些精力。

当您使用证书获取RSACryptoServiceProvider时,底层的CryptoAPI提供程序真正重要。默认情况下,当您使用'makecert'创建证书时,它是“RSA-FULL”,它仅支持用于签名的SHA1哈希值。您需要支持SHA2的新“RSA-AES”。

因此,您可以使用其他选项创建证书:-sp“Microsoft Enhanced RSA and AES Cryptographic Provider”(或等效的-sy 24),然后您的代码看起来像(在.NET 4.0中):

var rsa = signerCertificate.PrivateKey as RSACryptoServiceProvider;
//
byte[] signature = rsa.SignData(data, CryptoConfig.CreateFromName("SHA256"));

如果您无法更改颁发证书的方式,则会有一个半连接的解决方法,该解决方案基于以下事实:默认情况下创建的RSACryptoServiceProvider支持SHA2。所以,下面的代码也可以工作,但有点丑陋: (这段代码的作用是创建一个新的RSACryptoServiceProvider并从我们从证书中获取的密钥导入密钥)

var rsa = signerCertificate.PrivateKey as RSACryptoServiceProvider;
// Create a new RSACryptoServiceProvider
RSACryptoServiceProvider rsaClear = new RSACryptoServiceProvider();
// Export RSA parameters from 'rsa' and import them into 'rsaClear'
rsaClear.ImportParameters(rsa.ExportParameters(true));
byte[] signature = rsaClear.SignData(data, CryptoConfig.CreateFromName("SHA256"));

希望您觉得这很有帮助。