Rijndael 密码术无法在 Windows Server 2012 上运行

Rijndael cryptography not working on Windows Server 2012

我有一个 Windows 应用程序 (x64),它在 Winodws 7、8 和现在的 10 上运行良好。今天我们在 运行 [ 下的程序失败了=28=] 2012 服务器。当我们查看事件日志时,我们发现了一个源自 System.Security.Cryptography.RijndaelManaged..ctor() 的错误(不幸的是日志没有给我们完整的路径)。

我使用了 Rijndael 算法来加密我程序中的敏感数据。程序做的第一件事是检索加密的配置文件并解密它以获得所有设置。这是我的程序没有启动的地方。

这是我程序中的解密方法:

public static string Decrypt(string cipherText, string passPhrase)
{
    byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
    using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
    {
        byte[] keyBytes = password.GetBytes(keysize / 8);
        using (RijndaelManaged symmetricKey = new RijndaelManaged())
        {
            symmetricKey.Mode = CipherMode.CBC;
            using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes))
            {
                using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
                {
                    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                    {
                        byte[] plainTextBytes = new byte[cipherTextBytes.Length];
                        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                        return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                    }
                }
            }
        }
    }
}

这是我在日志中收到的错误消息:

Application: Postbag.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.InvalidOperationException at System.Security.Cryptography.RijndaelManaged..ctor() at Common.StringCipher.Decrypt(System.String, System.String) at Common.Conf..cctor() Exception Info: System.TypeInitializationException at Common.Conf.get_DataProvider() at Postbag.FormMain..ctor() at Postbag.Program.Main()

新服务器也有相同版本的 .Net 框架。

RijndaelManaged 类不符合 FIPS,您的服务器似乎具有安全策略系统加密:使用符合 FIPS 的算法进行加密、散列和签名

在知识库文章 "System cryptography: Use FIPS compliant algorithms for encryption, hashing, and signing" security setting effects in Windows XP and in later versions of Windows 中说:

Microsoft .NET Framework applications such as Microsoft ASP.NET only allow for using algorithm implementations that are certified by NIST to be FIPS 140 compliant. Specifically, the only cryptographic algorithm classes that can be instantiated are those that implement FIPS-compliant algorithms. The names of these classes end in "CryptoServiceProvider" or "Cng." Any attempt to create an instance of other cryptographic algorithm classes, such as classes with names ending in "Managed," cause an InvalidOperationException exception to occur

所以 disable the security policy (from the SecPol.msc tool) or use a FIPS compliant implementation. Unfortunately Rijndael doesn't have such implementation so you might want to see if AesCng or AesCryptoServiceProvider matches your needs because AES is the formal implementation of what started as Rijndael. Based on the blog Is RijndaelManaged class FIPS compliant? from Prateek Kr Dubey 我得出结论,用 RijdaelManaged 加密的数据可以用 AesCngAesCryptoServiceProvider 解密。

为了完整起见,我使用 RijnDaelManaged class 创建了一个加密方法,并在这一行修改了您的代码示例:

using (RijndaelManaged symmetricKey = new RijndaelManaged())

阅读

using (var symmetricKey = new AesCryptoServiceProvider()) // or new AesCng()

并且确实能够解密字符串。