使用 CFB-8 模式的 Mono.Security.Cryptography RijndaelManaged 类问题

标签 mono monodevelop

我写信是为了报告有关密码学问题。使用 System.Security.Cryptography 中的 RijndaelManaged 类会出现此问题。对我来说,将 RijndaelManagedCFB-8 (FeedbackSize = 8) 模式一起使用而无需填充 (PaddingMode.None) 非常重要。这样的设置配置使加密数据大小等于解密数据大小。

不幸的是,Mono(Mono Compiler for MVS2010 IDE v2.0.8152)编译的代码在数据加密时抛出异常,并显示消息:

[Unhandled Exception: System.Security.Cryptography.CryptographicException: invalid block length at Mono.Security.Cryptography.SymmetricTransform.FinalEncrypt]. 

我使用 native Visual Studio 2010 编译器在 Windows XP 和 Windows 7 下使用 .NET Framework 4.0 进行了测试。我发现 native Microsoft .NET 编译器不会引发任何异常,并且代码示例运行良好。

下面我粘贴了两个示例(重现代码),一个用于 Mono,它抛出异常,另一个用于 native C# 编译器,在这种情况下没有异常。此外,我还粘贴了在线编译器的链接来测试代码。

为什么 Mono 编译器会抛出此异常?


Mono代码示例(用于测试的在线编译器,Compile Online)

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace Dela.Mono.Examples
{
   public class HelloWorld
   {
      public static void Main(string[] args)
      {
         string plainText = "This will be encrypted.";
            string plainText2 = "";

            RijndaelManaged aesAlg = new RijndaelManaged();

            aesAlg.BlockSize = 128;
            aesAlg.KeySize = 256;
            aesAlg.Mode = CipherMode.CFB;
            aesAlg.FeedbackSize = 8;
            aesAlg.Padding = PaddingMode.None;

            aesAlg.GenerateKey();
            aesAlg.GenerateIV();

            ICryptoTransform encryptor = aesAlg.CreateEncryptor();

            MemoryStream msEncrypt = new MemoryStream();
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) {
                    swEncrypt.Write(plainText);
                }
            }

            Console.WriteLine(msEncrypt.ToArray().Length); 
            Console.WriteLine(System.Text.Encoding.UTF8.GetString(msEncrypt.ToArray()));

            byte[] customArray = msEncrypt.ToArray();

            ICryptoTransform decryptor = aesAlg.CreateDecryptor();

            MemoryStream msDecrypt = new MemoryStream(customArray);
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) {
                using (StreamReader swDecrypt = new StreamReader(csDecrypt)) {
                    plainText2 = swDecrypt.ReadToEnd();
                }
            }

            Console.WriteLine(plainText2.Length); 
            Console.WriteLine(plainText2);


      }
   } 
}

native C# 代码示例(用于测试的在线编译器,Compile Online)

// Rextester.Program.Main is the entry point for your code. Don't change it.

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            string plainText = "This will be encrypted.";
            string plainText2 = "";

            RijndaelManaged aesAlg = new RijndaelManaged();

            aesAlg.BlockSize = 128;
            aesAlg.KeySize = 256;
            aesAlg.Mode = CipherMode.CFB;
            aesAlg.FeedbackSize = 8;
            aesAlg.Padding = PaddingMode.None;

            aesAlg.GenerateKey();
            aesAlg.GenerateIV();

            ICryptoTransform encryptor = aesAlg.CreateEncryptor();

            MemoryStream msEncrypt = new MemoryStream();
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) {
                    swEncrypt.Write(plainText);
                }
            }

            Console.WriteLine(msEncrypt.ToArray().Length); 
            Console.WriteLine(System.Text.Encoding.UTF8.GetString(msEncrypt.ToArray()));

            byte[] customArray = msEncrypt.ToArray();

            ICryptoTransform decryptor = aesAlg.CreateDecryptor();

            MemoryStream msDecrypt = new MemoryStream(customArray);
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) {
                using (StreamReader swDecrypt = new StreamReader(csDecrypt)) {
                    plainText2 = swDecrypt.ReadToEnd();
                }
            }

            Console.WriteLine(plainText2.Length); 
            Console.WriteLine(plainText2);
        }
    }
}

最佳答案

该错误已修复。源代码可以从 mono GIT 存储库中获取。

主控:e094d3dc0cf186f1de32d5340d847dc18aeca0e2

单声道2-10:98e4842eb19dfd60000ada19e9bfb265fad7c84b

关于使用 CFB-8 模式的 Mono.Security.Cryptography RijndaelManaged 类问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12432365/

相关文章:

.net - Mono 和 TransactionScope

monodevelop - 在 Xamarin Studio 中隐藏某些警告

iphone - MonoDevelop 的编辑器对你来说慢吗?

.net - 应用程序在模拟器中运行,但在部署中给出 'could not resolve error'

c# - 如何在 Unity 3d 中跳转?

mono - Kestrel ASP.NET 5 错误时出现空白白屏

c# - Android c# 按钮重叠

ubuntu - 如何从我的局域网访问mono development xsp2?

c# - 为 .NET 和单声道编写 C# 应用程序的指南

xamarin.ios - 如何从 NSData 到 byte[]