程序永远不会打印出“测试”,除非我在它上面设置一个断点并跨过我自己。我不明白发生了什么。感谢任何帮助。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
string testKey = "lkirwf897+22#bbtrm8814z5qq=498j5";
string testIv = "741952hheeyy66#cs!9hjv887mxx7@8y";
string testValue = "random";
string encryptedText = EncryptRJ256(testKey, testIv, testValue);
string decryptedText = DecryptRJ256(testKey, testIv, encryptedText);
Console.WriteLine("encrypted: " + encryptedText);
Console.WriteLine("decrypted: " + decryptedText);
Console.WriteLine("test");
}
public static string DecryptRJ256(string key, string iv, string text)
{
string sEncryptedString = text;
RijndaelManaged myRijndael = new RijndaelManaged();
myRijndael.Padding = PaddingMode.Zeros;
myRijndael.Mode = CipherMode.CBC;
myRijndael.KeySize = 256;
myRijndael.BlockSize = 256;
byte[] keyByte = System.Text.Encoding.ASCII.GetBytes(key);
byte[] IVByte = System.Text.Encoding.ASCII.GetBytes(iv);
ICryptoTransform decryptor = myRijndael.CreateDecryptor(keyByte, IVByte);
byte[] sEncrypted = Convert.FromBase64String(sEncryptedString);
byte[] fromEncrypt = new byte[sEncrypted.Length + 1];
MemoryStream msDecrypt = new MemoryStream(sEncrypted);
CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
return Encoding.ASCII.GetString(fromEncrypt);
}
public static string EncryptRJ256(string key, string iv, string text)
{
string sToEncrypt = text;
RijndaelManaged myRijndael = new RijndaelManaged();
myRijndael.Padding = PaddingMode.Zeros;
myRijndael.Mode = CipherMode.CBC;
myRijndael.KeySize = 256;
myRijndael.BlockSize = 256;
byte[] keyByte = Encoding.ASCII.GetBytes(key);
byte[] IVByte = Encoding.ASCII.GetBytes(iv);
ICryptoTransform encryptor = myRijndael.CreateEncryptor(keyByte, IVByte);
MemoryStream msEncrypt = new MemoryStream();
CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
byte[] toEncrypt = System.Text.Encoding.ASCII.GetBytes(sToEncrypt);
csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
csEncrypt.FlushFinalBlock();
byte[] encrypted = msEncrypt.ToArray();
return Convert.ToBase64String(encrypted);
}
}
编辑:
尝试Debug.WriteLine
Debug.WriteLine("encrypted: " + encryptedText);
Debug.WriteLine("decrypted: " + decryptedText);
Debug.WriteLine("test");
输出:
已加密:T4hdAcpP5MROmKLeziLvl7couD0o + 6EuB / Kx29RPm9w =
解密:randomtest
不确定为什么它不打印行终止符。
答案 0 :(得分:5)
myRijndael.Padding = PaddingMode.Zeros;
myRijndael.BlockSize = 256;
这是问题的根源,您加密的数据用零填充以获得32字节(32 x 8 = 256)的倍数的块大小。您将这些二进制零返回到解密值中。关于它们的棘手问题是调试器无法显示它们。哪个好,你希望通过ASCII往返的值,你可以在解密后再次删除零。解密代码也需要一些工作,你对解密数据的大小有太多考虑。修正:
MemoryStream fromEncrypt = new MemoryStream();
MemoryStream msDecrypt = new MemoryStream(sEncrypted);
CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
byte[] buffer = new byte[4096];
for (; ; ) {
int len = csDecrypt.Read(buffer, 0, buffer.Length);
if (len == 0) break;
fromEncrypt.Write(buffer, 0, len);
}
var result = Encoding.ASCII.GetString(fromEncrypt.GetBuffer(), 0, (int)fromEncrypt.Length);
return result.Trim('\0');
你应该顺便处理流,使用使用语句。
答案 1 :(得分:0)
虽然这适用于我在Linux上使用Mono,但我确实看到decryptedText长度为33个字符 - 它由字符'r','a','n','d','o','m组成'跟随了27个NUL角色。 (我以前推测填充字节可能是未初始化的,但是查看它看起来很明确的代码。)我推测Visual Studio中的控制台输出窗口将NUL字符解释为输出结束,因此停止之后打印其他任何东西 - 包括WriteLine的行终止符和“test”字符串。我这里没有Visual Studio来测试它,但我认为你应该能够轻松地验证或反驳它。
答案 2 :(得分:0)
您的加密/解密代码中存在一个问题:由于您使用PaddingMode.Zeros
,因此在解密后,您无法说出原始数据的结束位置,并且您收到了“随机”后跟零字节。如果你想切换到例如PaddingMode.PKCS7
,并且正确使用CryptoStream.Read
调用的返回值,您只会收到原始文本,即“随机”:
var decryptedSize = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
return Encoding.ASCII.GetString(fromEncrypt, 0, decryptedSize);
即使我认为不应该将NUL字节写入控制台是一个问题,我肯定会先尝试删除它们,特别是在看到这种奇怪的行为时。