我正在写关于加密问题的报告。使用RijndaelManaged
中的System.Security.Cryptography
类会发生此问题。对于我来说,使用RijndaelManaged
和CFB-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].
我使用本机Visual Studio 2010编译器在Windows XP和Windows 7下使用.NET framework 4.0进行了测试。我发现本机Microsoft .NET编译器不会抛出任何异常,并且代码示例运行良好。
下面我贴了两个例子(Repro代码),一个用于Mono,它抛出一个异常,一个用于本机C#编译器,在这种情况下没有例外。此外,我还粘贴了在线编译器的链接来测试代码。
为什么Mono Compiler会抛出此异常?
单声道代码示例(用于测试的在线编译器,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);
}
}
}
答案 0 :(得分:2)
错误已修复。源可以从单GIT存储库中获取。
master:e094d3dc0cf186f1de32d5340d847dc18aeca0e2
mono-2-10:98e4842eb19dfd60000ada19e9bfb265fad7c84b