2017-05-29 73 views
10

我有一箇舊功能在2013年編寫的解密xml被另一個程序加密。EncryptedXml DecryptDocument方法錯誤.Net框架更新後

的代碼是真的簡單

 public static void Decrypt(XmlDocument Doc) 
    { 
     // Check the arguments. 
     if (Doc == null) 
      throw new ArgumentNullException("Doc"); 

     // Create a new EncryptedXml object. 
     EncryptedXml exml = new EncryptedXml(Doc); 

     // Decrypt the XML document. 
     exml.DecryptDocument(); 

    } 

它的工作就像一個魅力直到最近,我們的一些客戶開始他們的架構升級到4.6.2,因此該方法DecryptDocument()停止工作。現在它會拋出一個異常「算法組」無效「。如果我刪除.net框架4.6.2它再次工作。

link中的示例代碼將重現該錯誤,它將成功加密,然後無法解密。

我正在使用A3證書,pendrive令牌。任何人都遇到過這個問題?在.net 4.6.2中有任何解決方法?

編輯1:

堆棧跟蹤:

at System.Security.Cryptography.CngAlgorithmGroup..ctor(String algorithmGroup) at System.Security.Cryptography.CngKey.get_AlgorithmGroup() at System.Security.Cryptography.RSACng..ctor(CngKey key) at System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(X509Certificate2 certificate) at System.Security.Cryptography.CngLightup.GetRSAPrivateKey(X509Certificate2 cert) at System.Security.Cryptography.Xml.EncryptedXml.DecryptEncryptedKey(EncryptedKey encryptedKey) at System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData encryptedData, String symmetricAlgorithmUri) at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument() at Criptografar.Program.Decrypt(XmlDocument Doc) in C:\Users\leoka\Documents\Visual Studio 2017\Projects\ConsoleApp4\Criptografar\Program.cs:line 152 at Criptografar.Program.Main(String[] args) in C:\Users\leoka\Documents\Visual Studio 2017\Projects\ConsoleApp4\Criptografar\Program.cs:line 83

+1

你有完整的堆棧跟蹤嗎? –

+0

客戶是否完全重建?讓客戶在項目中創建bin文件夾的副本。然後刪除bin文件夾並重新編譯。我懷疑錯誤是由於編譯器的依賴。編譯器對Net Version沒有任何依賴性,所以當安裝新的Net時需要完整的重新編譯。編譯器不會自動完成一個完整的編譯。 – jdweng

+0

@jdweng即使在我的開發機器上也失敗了,我開始了一個新項目,粘貼了這個[link]的示例代碼(https://msdn.microsoft.com/en-us/library/ms148633(v = vs.110) )的.aspx)。它未能解密。 –

回答

1

我無法自己再現問題 - 我沒有「pendrive令牌」,我懷疑這是問題 - 所以這是猜測。 Windows中有兩代密碼API - the "old" one"new generation" one, known as CNG。 現在,如果您查看在堆棧跟蹤中途出現的source code for the CngLightup type,特別是DetectRsaCngSupport方法,您會發現.NET框架嘗試使用新一代API(如果可能)。我的猜測是「pendrive token」設備不支持新的API。您可以通過強制使用舊的API來驗證這一點。不幸的是,似乎沒有一個公共配置標誌來控制這個標誌,所以你必須採取基於反射的黑客行爲。例如,你可以把這樣的事情在你的程序的開始,使之運行一次,您嘗試解密操作前:

var cngLightupType = typeof(EncryptedXml).Assembly.GetType("System.Security.Cryptography.CngLightup"); 
    var preferRsaCngField = cngLightupType.GetField("s_preferRsaCng", BindingFlags.Static | BindingFlags.NonPublic); 
    var getRsaPublicKeyField = cngLightupType.GetField("s_getRsaPublicKey", BindingFlags.Static | BindingFlags.NonPublic); 
    var getRsaPrivateKeyField = cngLightupType.GetField("s_getRsaPrivateKey", BindingFlags.Static | BindingFlags.NonPublic); 
    preferRsaCngField.SetValue(null, new Lazy<bool>(() => false)); 
    getRsaPublicKeyField.SetValue(null, null); 
    getRsaPrivateKeyField.SetValue(null, null); 

請注意,這是非常哈克,不是線程安全的,錯誤處理被省略等。如果您確認CNG使用是問題,那麼您可以要求「pendrive令牌」供應商提供與CNG配合使用的驅動程序。或者你可以忍受上面的黑客攻擊,重寫更安全。

+0

非常感謝,我測試過它,它工作。現在我可以更深入地探究這個問題,我知道究竟出了什麼問題。如果有的話,這個黑客會給我一些時間來尋找更好的解決方案。 –

2

有在.net 4.6.2影響EncrtyptedXml一些運行時的變化 - 看https://msdn.microsoft.com/en-us/library/mt670901(v=vs.110).aspx#Anchor_5

+0

感謝您的信息,但是這個鏈接並沒有說任何關於不能使用A3證書進行解密的問題,我發現@silkfire評論甚至不是我可以得到的RSAPrivateKey的一個實例。我不認爲這是令牌製造商的問題,因爲使用不同令牌的多個客戶端報告相同的問題。另外,它並不表示如何解決問題。 –

0

我碰到了一些非常類似的今天,原來是在.NET 4.6.2中的一個錯誤: https://github.com/Microsoft/dotnet/issues/341

根據這個問題,有兩種解決方法:

1)升級操作系統到Windows Server 2012R2或更高版本,2)裝載 用戶配置文件。

+1

謝謝你的建議。我使用Windows Server 2012 R2安裝了一臺虛擬機,我應用了所有的Windows更新,但仍然無法使用.net framework 4.6.2。我正在使用桌面應用程序,因此配置IIS以加載用戶配置文件不適合。 –