2012-05-20 75 views
4

我有一個智能卡,我需要用這個簽名文件。 這是一個很大的問題,因爲我在stackover看到。使用SHA256簽名

我不能使用RSACryptoServiceProvider,bkz它不支持RSA-SHA256 alogrithm。

起初,我用的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算法簽署。 當我changw哈希算法這樣

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

我米得到一個

錯誤: 「未指定的錯誤」。

那是我的問題, 什麼是溶劑,或者我應該使用哪個庫?

感謝您的任何建議..

回答

12

的RSACryptoServiceProvider確實與基於SHA2的簽名工作,但你必須要一些努力投入到它。

當您使用證書來獲取您的RSACryptoServiceProvider時,它真的很重要CryptoAPI提供程序的底層。默認情況下,當您使用'makecert'創建證書時,它是「RSA-FULL」,它只支持SHA1哈希進行簽名。您需要支持SHA2的新「RSA-AES」。

因此,您可以使用其他選項創建證書:-sp「Microsoft增強型RSA和AES加密提供程序」(或等效的-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")); 

希望你找到這個有幫助。

+0

對於第二個解決方法(從證書中將證書導入到新的csp中),這對硬件密鑰的工作方式如何?這些密鑰可導出嗎? – ezile

相關問題