简体   繁体   中英

AES round trip producing random chars

So here's my mess. It returns random Unicode chars. I'm having it use the same key for both methods, as well as the same IV, and I'm using the same encoding for both of them. What's causing the random response?

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace FileFish
{
    class Program
    {
        public static void Main()
        {
            AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
            aes.GenerateIV();
            Console.WriteLine(Decrypt(Encoding.UTF8.GetBytes("APPLEAPPLEAPPLEAPPLEAPPLEAPPLEAP"), aes.IV, Encrypt(Encoding.UTF8.GetBytes("APPLEAPPLEAPPLEAPPLEAPPLEAPPLEAP"), aes.IV, "cheese")));
            Console.ReadKey(true);
        }

        private static byte[] Encrypt(byte[] key, byte[] iv, string plaintext)
        {
            AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
            aes.Key = key;
            aes.IV = iv;
            ICryptoTransform encryptor = aes.CreateEncryptor();
            MemoryStream ms = new MemoryStream();
            StreamWriter sw = new StreamWriter(new CryptoStream(ms, encryptor, CryptoStreamMode.Write));
            sw.Write(plaintext);
            return ms.ToArray();
        }

        private static string Decrypt(byte[] key, byte[] iv, byte[] ciphertext)
        {
            AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
            aes.Key = key;
            aes.IV = iv;
            ICryptoTransform decryptor = aes.CreateEncryptor();
            MemoryStream ms = new MemoryStream(ciphertext);
            StreamReader sr = new StreamReader(new CryptoStream(ms, decryptor, CryptoStreamMode.Read));
            return sr.ReadToEnd();
        }
    }
}

Your code sample is failing because the Encrypt method returns an empty array. Rather than trying to roll it yourself, you'd be better off using something that is proven to work.

The example from the AesCryptoServiceProvider documentation works in place of your Encrypt and Decrypt methods from your sample code:

static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
    // Check arguments.
    if (plainText == null || plainText.Length <= 0)
        throw new ArgumentNullException("plainText");
    if (Key == null || Key.Length <= 0)
        throw new ArgumentNullException("Key");
    if (IV == null || IV.Length <= 0)
        throw new ArgumentNullException("Key");
    byte[] encrypted;
    // Create an AesCryptoServiceProvider object
    // with the specified key and IV.
    using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
    {
        aesAlg.Key = Key;
        aesAlg.IV = IV;

        // Create a decrytor to perform the stream transform.
        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

        // Create the streams used for encryption.
        using (MemoryStream msEncrypt = new MemoryStream())
        {
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    //Write all data to the stream.
                    swEncrypt.Write(plainText);
                }
                encrypted = msEncrypt.ToArray();
            }
        }
    }

    // Return the encrypted bytes from the memory stream.
    return encrypted;
}

static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
{
    // Check arguments.
    if (cipherText == null || cipherText.Length <= 0)
        throw new ArgumentNullException("cipherText");
    if (Key == null || Key.Length <= 0)
        throw new ArgumentNullException("Key");
    if (IV == null || IV.Length <= 0)
        throw new ArgumentNullException("Key");

    // Declare the string used to hold
    // the decrypted text.
    string plaintext = null;

    // Create an AesCryptoServiceProvider object
    // with the specified key and IV.
    using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
    {
        aesAlg.Key = Key;
        aesAlg.IV = IV;

        // Create a decrytor to perform the stream transform.
        ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

        // Create the streams used for decryption.
        using (MemoryStream msDecrypt = new MemoryStream(cipherText))
        {
            using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
            {
                using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                {

                    // Read the decrypted bytes from the decrypting stream
                    // and place them in a string.
                    plaintext = srDecrypt.ReadToEnd();
                }
            }
        }
    }

    return plaintext;
}

Also, not that it's the cause of this problem, but: http://blogs.msdn.com/b/shawnfa/archive/2005/11/10/491431.aspx

Don't Roundtrip Ciphertext Via a String Encoding

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM