在C#UTF8之前的有效载荷垃圾字节到AES到Base64的转换
问题描述:
我一直试图在方法中使用AES加密和解密UTF-8字符串,然后将其作为Base64字符串返回,以实现正确的IV练习。使用this问题作为参考,我已将生成的IV预加载到Base64转换之前的字节数组中。我遇到了一个问题,解密方法返回的UTF-8字符串只有50个字符的随机垃圾(加密工件?)。我不认为这个问题与加密有关,因为解密方法会一直返回加密的字符串。我认为问题在于其他转换步骤之一,但我无法查看这可能来自哪里。任何帮助将不胜感激。在C#UTF8之前的有效载荷垃圾字节到AES到Base64的转换
加密方法
public static string EncryptString(string input, string key)
{
using (var aes = new AesCryptoServiceProvider())
{
aes.Key = System.Convert.FromBase64String(key);
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
byte[] rawData = Encoding.UTF8.GetBytes(input);
// IV is the 16 byte AES Initialization Vector
aes.GenerateIV();
using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
{
using (var ms = new MemoryStream())
{
ms.Write(aes.IV, 0, aes.IV.Length); // aes.IV.Length should be 16
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(rawData, 0, rawData.Length);
cs.FlushFinalBlock();
}
byte[] encryptedData = ms.ToArray();
// this will hold the IV prepended to the encrypted data
byte[] output = new byte[aes.IV.Length + encryptedData.Length];
Array.Copy(aes.IV, output, aes.IV.Length); // save the iv
Array.Copy(encryptedData, 0, output, aes.IV.Length, encryptedData.Length); // save the data
// now encode the whole thing as base 64
return System.Convert.ToBase64String(output);
}
}
}
}
解密方法
public static string DecryptString(string input, string key)
{
using (var aes = new AesCryptoServiceProvider())
{
aes.Key = Convert.FromBase64String(key);
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
byte[] rawData = Convert.FromBase64String(input);
byte[] IV = new byte[16]; // aes.IV.Length should be 16
Array.Copy(rawData, IV, IV.Length);
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, aes.CreateDecryptor(aes.Key, IV), CryptoStreamMode.Write))
{
using (var binaryWriter = new BinaryWriter(cs))
{
binaryWriter.Write(rawData,IV.Length ,rawData.Length - IV.Length);
}
}
return Encoding.UTF8.GetString(ms.ToArray());
}
}
}
我的测试
static void Main(string[] args)
{
string payload = "My super secret string";
string key = "tR4mPn7mBQ8G6HWusyFnGk/gqdd/enWiUTr7YbhNrJg=";
Console.WriteLine(payload);
Console.WriteLine(key);
Console.WriteLine("");
string encrypted = EncryptString(payload, key);
Console.WriteLine(encrypted);
Console.WriteLine("");
string decrypted = DecryptString(encrypted, key);
Console.WriteLine(decrypted);
Console.WriteLine(decrypted.Length.ToString() + " " + encrypted.Length.ToString());
Console.ReadKey();
}
编辑补充 - 这是输出的一个例子:
XQ = F] d我的超级秘密串
答
您在EncryptString
写四输出两次?首先你有:
ms.Write(aes.IV, 0, aes.IV.Length); // aes.IV.Length should be 16
这是encryptedData
的开头。你那么IV和encryptedData
(其中已经包含了IV)复制到一个新的字节数组:
// this will hold the IV prepended to the encrypted data
byte[] output = new byte[aes.IV.Length + encryptedData.Length];
Array.Copy(aes.IV, output, aes.IV.Length); // save the iv
Array.Copy(encryptedData, 0, output, aes.IV.Length, encryptedData.Length); // save the data
静脉输液的翻倍是什么原因造成的额外的字节。
您不需要进行第二次复制。只是转换encryptedData
直接底座64返回:
return System.Convert.ToBase64String(encryptedData);
+0
这是正确的。我认为这是一个简单的错误。我疲惫的周五眼睛无法捕捉它。 –
检查输出为十六进制,你会看到这个问题,Base64是电脑,而不是人类。 – zaph