C# AES 加密/解密返回不正确的结果
C# AES encryption / decryption returning incorrect result
我已经根据此处的 MSDN 示例创建了一个简单的 AES 加密/解密服务:https://msdn.microsoft.com/en-us/library/system.security.cryptography.aes(v=vs.110).aspx
这是我的代码,带有调用函数和用于测试的硬编码密钥:
public class AesEncryptionService
{
private const int InitializationVectorLength = 16;
private static readonly byte[] Key = Convert.FromBase64String("W+jcxfBJm37AAZujiktg4qCdy3k8D+vIrj4exFxFpIY=");
public byte[] Encrypt(byte[] input)
{
using (var aes = Aes.Create())
{
aes.Key = Key;
Console.WriteLine("Key: " + Convert.ToBase64String(aes.Key));
Console.WriteLine("IV: " + Convert.ToBase64String(aes.IV));
Console.WriteLine("Input: " + Convert.ToBase64String(input));
using (var outputStream = new MemoryStream())
{
using (var encryptor = aes.CreateEncryptor())
using (var cryptoStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
using (var streamWriter = new StreamWriter(cryptoStream))
{
streamWriter.Write(input);
}
var output = outputStream.ToArray();
Console.WriteLine("Output: " + Convert.ToBase64String(output));
var encrypted = aes.IV.Concat(output).ToArray();
return encrypted;
}
}
}
public byte[] Decrypt(byte[] input)
{
var initializationVector = input.Take(InitializationVectorLength).ToArray();
input = input.Skip(InitializationVectorLength).ToArray();
using (var aes = Aes.Create())
{
aes.Key = Key;
aes.IV = initializationVector;
Console.WriteLine("Key: " + Convert.ToBase64String(aes.Key));
Console.WriteLine("IV: " + Convert.ToBase64String(aes.IV));
Console.WriteLine("Input: " + Convert.ToBase64String(input));
using (var outputStream = new MemoryStream())
{
using (var decryptor = aes.CreateDecryptor())
using (var inputStream = new MemoryStream(input))
using (var cryptoStream = new CryptoStream(inputStream, decryptor, CryptoStreamMode.Read))
{
cryptoStream.CopyTo(outputStream);
}
var output = outputStream.ToArray();
Console.WriteLine("Output: " + Convert.ToBase64String(output));
return output;
}
}
}
}
class Program
{
static void Main(string[] args)
{
var encryptionService = new AesEncryptionService();
var input = Guid.NewGuid().ToByteArray();
Console.WriteLine("Encrypting...");
var encrypted = encryptionService.Encrypt(input);
Console.WriteLine();
Console.WriteLine("Decrypting...");
var decrypted = encryptionService.Decrypt(encrypted);
Console.WriteLine();
Console.WriteLine("Input: " + Convert.ToBase64String(input));
Console.WriteLine("Output: " + Convert.ToBase64String(decrypted));
}
}
这是我得到的输出示例:
Encrypting...
Key: W+jcxfBJm37AAZujiktg4qCdy3k8D+vIrj4exFxFpIY=
IV: 7tb1BwOOcCdH/h1wdUmrtw==
Input: UsyLMdqbuUC5cVW/+p6vWA==
Output: 4KAhNOwNiNpmPxjvvx38cA==
Decrypting...
Key: W+jcxfBJm37AAZujiktg4qCdy3k8D+vIrj4exFxFpIY=
IV: 7tb1BwOOcCdH/h1wdUmrtw==
Input: 4KAhNOwNiNpmPxjvvx38cA==
Output: U3lzdGVtLkJ5dGVbXQ==
Input: UsyLMdqbuUC5cVW/+p6vWA==
Output: U3lzdGVtLkJ5dGVbXQ==
如您所见,解密后的输出与输入不匹配。我一定是在某处的代码中犯了错误,但我似乎无法发现它...有人可以帮忙吗?
Microsoft 的示例使用 StreamWriter
,它与 string
配合使用。您使用 byte[]
,但仍使用 StreamWriter
及其在对象上内部调用 ToString()
的重载成员 Write(object)
。当您在 byte[]
上调用 ToString()
时,您总是会得到 "System.Byte[]" 作为字符串。 13 个字节,与最终结果一样。实际上,如果在最后一行中替换
Console.WriteLine("Output: " + Convert.ToBase64String(decrypted));
和
Console.WriteLine("Output: " + Encoding.UTF8.GetString(decrypted));
这正是您所看到的字符串。
您应该使用 BinaryWriter
而不是 StreamWriter
。
我已经根据此处的 MSDN 示例创建了一个简单的 AES 加密/解密服务:https://msdn.microsoft.com/en-us/library/system.security.cryptography.aes(v=vs.110).aspx
这是我的代码,带有调用函数和用于测试的硬编码密钥:
public class AesEncryptionService
{
private const int InitializationVectorLength = 16;
private static readonly byte[] Key = Convert.FromBase64String("W+jcxfBJm37AAZujiktg4qCdy3k8D+vIrj4exFxFpIY=");
public byte[] Encrypt(byte[] input)
{
using (var aes = Aes.Create())
{
aes.Key = Key;
Console.WriteLine("Key: " + Convert.ToBase64String(aes.Key));
Console.WriteLine("IV: " + Convert.ToBase64String(aes.IV));
Console.WriteLine("Input: " + Convert.ToBase64String(input));
using (var outputStream = new MemoryStream())
{
using (var encryptor = aes.CreateEncryptor())
using (var cryptoStream = new CryptoStream(outputStream, encryptor, CryptoStreamMode.Write))
using (var streamWriter = new StreamWriter(cryptoStream))
{
streamWriter.Write(input);
}
var output = outputStream.ToArray();
Console.WriteLine("Output: " + Convert.ToBase64String(output));
var encrypted = aes.IV.Concat(output).ToArray();
return encrypted;
}
}
}
public byte[] Decrypt(byte[] input)
{
var initializationVector = input.Take(InitializationVectorLength).ToArray();
input = input.Skip(InitializationVectorLength).ToArray();
using (var aes = Aes.Create())
{
aes.Key = Key;
aes.IV = initializationVector;
Console.WriteLine("Key: " + Convert.ToBase64String(aes.Key));
Console.WriteLine("IV: " + Convert.ToBase64String(aes.IV));
Console.WriteLine("Input: " + Convert.ToBase64String(input));
using (var outputStream = new MemoryStream())
{
using (var decryptor = aes.CreateDecryptor())
using (var inputStream = new MemoryStream(input))
using (var cryptoStream = new CryptoStream(inputStream, decryptor, CryptoStreamMode.Read))
{
cryptoStream.CopyTo(outputStream);
}
var output = outputStream.ToArray();
Console.WriteLine("Output: " + Convert.ToBase64String(output));
return output;
}
}
}
}
class Program
{
static void Main(string[] args)
{
var encryptionService = new AesEncryptionService();
var input = Guid.NewGuid().ToByteArray();
Console.WriteLine("Encrypting...");
var encrypted = encryptionService.Encrypt(input);
Console.WriteLine();
Console.WriteLine("Decrypting...");
var decrypted = encryptionService.Decrypt(encrypted);
Console.WriteLine();
Console.WriteLine("Input: " + Convert.ToBase64String(input));
Console.WriteLine("Output: " + Convert.ToBase64String(decrypted));
}
}
这是我得到的输出示例:
Encrypting...
Key: W+jcxfBJm37AAZujiktg4qCdy3k8D+vIrj4exFxFpIY=
IV: 7tb1BwOOcCdH/h1wdUmrtw==
Input: UsyLMdqbuUC5cVW/+p6vWA==
Output: 4KAhNOwNiNpmPxjvvx38cA==
Decrypting...
Key: W+jcxfBJm37AAZujiktg4qCdy3k8D+vIrj4exFxFpIY=
IV: 7tb1BwOOcCdH/h1wdUmrtw==
Input: 4KAhNOwNiNpmPxjvvx38cA==
Output: U3lzdGVtLkJ5dGVbXQ==
Input: UsyLMdqbuUC5cVW/+p6vWA==
Output: U3lzdGVtLkJ5dGVbXQ==
如您所见,解密后的输出与输入不匹配。我一定是在某处的代码中犯了错误,但我似乎无法发现它...有人可以帮忙吗?
Microsoft 的示例使用 StreamWriter
,它与 string
配合使用。您使用 byte[]
,但仍使用 StreamWriter
及其在对象上内部调用 ToString()
的重载成员 Write(object)
。当您在 byte[]
上调用 ToString()
时,您总是会得到 "System.Byte[]" 作为字符串。 13 个字节,与最终结果一样。实际上,如果在最后一行中替换
Console.WriteLine("Output: " + Convert.ToBase64String(decrypted));
和
Console.WriteLine("Output: " + Encoding.UTF8.GetString(decrypted));
这正是您所看到的字符串。
您应该使用 BinaryWriter
而不是 StreamWriter
。