【问题标题】:EncryptedXml DecryptDocument method error after .Net framework update.Net 框架更新后的 EncryptedXml DecryptDocument 方法错误
【发布时间】:2017-10-30 05:31:08
【问题描述】:

我有一个 2013 年编写的旧函数,用于解密由另一个程序加密的 xml。

代码很简单

        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 framework 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

【问题讨论】:

  • 你有完整的堆栈跟踪吗?
  • 客户是否完全重建?让客户在项目中复制 bin 文件夹。然后删除bin文件夹并重新编译。我怀疑错误是由于编译器中的依赖关系造成的。编译器对网络版本没有任何依赖关系,因此当安装新网络时,需要重新编译。编译器不会自动进行完整编译。
  • @jdweng 它甚至在我的开发机器上也失败了,我开始了一个新项目,粘贴了这个link的示例代码。解密失败。
  • 我会首先比较 .proj 文件(它们是 ASCII),以确保没有更改设置。 VS 2013 更改了很多默认设置。 VS2013 将字符编码的默认值从 UTF8 更改为 Unicode,这可以解释这个问题。我认为问题在于 VS 而不是网络库。只需更改网络库一个完全重建的项目就可以了。升级 Net 时,Microsoft 偶尔会更改默认设置,但这是不寻常的。
  • 我相当有信心这是一个 .net 框架问题。该程序是为 .NET 4.0 编译的。如果我复制到新安装了 .NET 4.6.2 的虚拟机,该程序将无法运行。如果在同一台机器上我删除 .net 框架并安装 4.5.2,程序将正常工作。我尝试重新编译程序以 .net 框架 4.6.2 为目标,我进行了干净的重建,但它仍然无法正常工作。该程序的旧版本于 2013 年编译,在 .NET 4.6.2 中也停止工作。

标签: c# xml encryption x509certificate2 encryption-asymmetric


【解决方案1】:

我自己无法重现问题 - 我没有我怀疑是问题的“pendrive 令牌” - 所以这是猜测。 Windows 中有两代加密 API - the "old" one"new generation" one, known as CNG。 现在,如果您查看堆栈跟踪中出现的source code for the CngLightup type,特别是DetectRsaCngSupport 方法,您会看到.NET 框架尽可能尝试使用新一代API。我的猜测是“pendrive 令牌”设备不支持新的 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);

请注意,它非常 hacky,不是线程安全的,省略了错误处理等。如果您确认 CNG 的使用是问题所在,您可以要求“pendrive 令牌”供应商提供与 CNG 一起使用的驱动程序.或者你可以接受上面的黑客攻击,为了更安全而重写。

【讨论】:

  • 非常感谢,我测试了,它工作。既然我知道到底出了什么问题,我就可以更深入地研究这个问题。如果有的话,这个技巧会让我有时间找到更好的解决方案。
【解决方案2】:

我今天遇到了非常相似的问题,结果证明是 .NET 4.6.2 中的一个错误: https://github.com/Microsoft/dotnet/issues/341

根据这个问题,有两种变通方法:

1) 将操作系统升级到 Windows Server 2012R2 或更新版本,2) 加载 用户个人资料。

【讨论】:

  • 感谢您的建议。我用 Windows Server 2012R2 安装了一个虚拟机,我应用了所有 Windows 更新,但它仍然不适用于 .net framework 4.6.2。我正在使用桌面应用程序,因此不适合配置 IIS 以加载用户配置文件。
【解决方案3】:

.Net 4.6.2 中有一些运行时更改会影响 EncrtyptedXml - 请参阅 https://msdn.microsoft.com/en-us/library/mt670901(v=vs.110).aspx#Anchor_5

【讨论】:

  • 感谢您的信息,但此链接没有说明无法使用 A3 证书进行解密,@silkfire 评论我发现我什至无法获得 RSAPrivateKey 的实例。我不认为这是令牌制造商的问题,因为使用不同令牌的多个客户报告了相同的问题。另外,也没有说明如何解决问题。
猜你喜欢
  • 1970-01-01
  • 2022-08-22
  • 2019-02-24
  • 2018-01-24
  • 1970-01-01
  • 2015-04-19
  • 2015-12-21
  • 2020-05-30
  • 1970-01-01
相关资源
最近更新 更多