C#AES加密/解密返回错误结果

时间:2015-08-29 22:29:04

标签: c# .net encryption cryptography aes

我已根据此处的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==

如您所见,解密输出与输入不匹配。我必须在代码中犯错,但我似乎无法发现它......任何人都可以帮忙吗?

1 个答案:

答案 0 :(得分:2)

Microsoft的示例使用StreamWriter,它与string一起使用。您使用的是byte[],但仍使用StreamWriter及其内部在对象上调用Write(object)的重载成员ToString()。当您在ToString()上致电byte[]时,您总是将“System.Byte []”作为字符串。 13个字节,就像最终结果一样。实际上,如果在最后一行中你替换

Console.WriteLine("Output: " + Convert.ToBase64String(decrypted));

Console.WriteLine("Output: " + Encoding.UTF8.GetString(decrypted));

这正是你看到的字符串。

您应该使用BinaryWriter代替StreamWriter