SHA256 簽名在 .NET 4.5 中停止工作
我們有一段程式碼創建了一個 SigningCredentials 對象,用於使用 SHA256 算法對 xml 文件進行簽名。它與 .NET 3.5 完美配合。但是,當我們將程式碼庫升級到 .NET 4.5 時,它就會停止工作。相同的程式碼,相同的證書!我花了幾個小時在網際網路上調試和搜尋,但沒有任何運氣。
誰能告訴我這裡的問題是什麼?先感謝您。
創建 SigningCredentials 的程式碼:
public SigningCredentials CreateSigningCredentials(X509Certificate2 cert) { var ski = new SecurityKeyIdentifier(new X509RawDataKeyIdentifierClause(cert)); return new SigningCredentials(new X509AsymmetricSecurityKey(cert), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "http://www.w3.org/2001/04/xmlenc#sha256", ski); }例外:
[CryptographicException: Invalid algorithm specified. ] System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) +41 System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 cbHash, ObjectHandleOnStack retSignature) +0 System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash) +118 System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash) +334 System.Security.Cryptography.RSAPKCS1SignatureFormatter.CreateSignature(Byte[] rgbHash) +321 System.IdentityModel.SignedXml.ComputeSignature(HashAlgorithm hash, AsymmetricSignatureFormatter formatter, String signatureMethod) +323 System.IdentityModel.SignedXml.ComputeSignature(SecurityKey signingKey) +690 System.IdentityModel.EnvelopedSignatureWriter.ComputeSignature() +338 System.IdentityModel.EnvelopedSignatureWriter.OnEndRootElement() +278 System.IdentityModel.Metadata.MetadataSerializer.WriteEntityDescriptor(XmlWriter inputWriter, EntityDescriptor entityDescriptor) +1109
雖然這個問題是在大約一年前提出的,但最近收到了一些贊成票,這可能表明其他一些人也遇到了同樣的問題。希望這個答案可以幫助:) 簡而言之,錯誤不會發生在所有機器上,而只會發生在其中一些機器上。我想這取決於在特定機器上註冊了哪些 CSP。無論如何,在我的具體情況下,證書是使用“Microsoft RSA SChannel …”或“Microsoft strong cryptographic provider”作為 CSP 生成的。我生成了一個新證書,但使用“Microsoft Enhanced RSA and AES Cryptographic Provider”作為 CSP,它的 SHA256 簽名開始為我工作。
一些參考資料:
<https://social.msdn.microsoft.com/Forums/vstudio/en-US/e391ba75-ce6e-431c-bfc9-26a71ae1b033/sha256-signing-stops-working-in-net-45?forum=Geneva> _可以看到,感謝幫助我解決這個問題的 Paul)
<http://hintdesk.com/c-how-to-fix-invalid-algorithm-specified-when-signing-with-sha256/>
XmlDsig 有同樣的問題(試圖用 RSA-SHA256 算法對 xml 文件進行封裝簽名)。首先我得到了例外
System.Security.Cryptography.CryptographicException:無法為提供的簽名算法創建 SignatureDescription。
然後我發現提到
RSAPKCS1SHA256SignatureDescription- RSA-SHA256 簽名的簽名描述實現。此處的完整實施:http:
//clrsecurity.codeplex.com/SourceControl/changeset/view/47833#269110或此處:https ://gist.github.com/sneal/f35de432115b840c4c1f
您必須為每個 appdomain 手動呼叫一次:
CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");之後我得到了一個新的例外:
System.Security.Cryptography.CryptographicException:指定的算法無效。
這讓我想到了你的問題。閱讀建議的文章後,我使用
Microsoft Enhanced RSA and AES Cryptographic Provider.令我驚訝的是,這個新證書使我能夠成功地進行簽名。
經過更多調查後,我在這裡找到了 Andrew 的有趣答案<https://stackoverflow.com/a/17285774/328785>,他曾經在那里
RSACryptoServiceProvider為SignedXml課堂準備 SecretKey。特別是這部分(我的解釋):var store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly); var certificates = store.Certificates.Find(X509FindType.FindBySerialNumber, "54dba096", true); var certificate = certificates[0]; // next three lines var cspParams = new CspParameters(24) { KeyContainerName = "XML_DSIG_RSA_KEY" }; var key = new RSACryptoServiceProvider(cspParams); key.FromXmlString(certificate.PrivateKey.ToXmlString(true)); SignedXml sxml = new SignedXml(doc); sxml.SigningKey = key;即使使用舊鑰匙,這個解決方案也能正常工作!