1

So, I am having an issue with decrypting the decoded base64 aes string. Is this possible? I wrote a small console program to work this out but no luck. Here is my example:

enter image description here

As depicted, I have successfully converted the base64 back the aes encrypted string, but when I try to decrypt it I get more junk. If a code snippet is need let me. Thank you all for your help :) UPDATE: Code snippet for decrypting method

static void Main(string[] args)
    {
        string plainText;
        string decrypted;
        string decryptedFromB64EncodedDecoded;
        string fromBase64ToEncryptedText;
        string encryptedText;
        string encryptedTextBase64;
        byte[] encryptedBytes;

        byte[] encryptedBytes2;
        byte[] encryptedBytesBase64;

        RijndaelManaged crypto = new RijndaelManaged();

        UTF8Encoding UTF = new UTF8Encoding();

        Console.WriteLine("Please put in the text to be encrypted.");
        plainText = Console.ReadLine();

        try
        {
            encryptedBytes = encrypt(plainText, crypto.Key, crypto.IV);
            encryptedText = Encoding.ASCII.GetString(encryptedBytes);
            //encryptedBytes2 = Encoding.ASCII.GetBytes(encryptedText);

            encryptedTextBase64 = toBase64String(encryptedText);
            encryptedBytesBase64 = fromBase64String(encryptedTextBase64);

            fromBase64ToEncryptedText = Encoding.ASCII.GetString(encryptedBytesBase64);

            encryptedBytes2 = Encoding.ASCII.GetBytes(fromBase64ToEncryptedText);

            decrypted = decrypt(encryptedBytes, crypto.Key, crypto.IV);
            decryptedFromB64EncodedDecoded = decrypt(encryptedBytes2, crypto.Key, crypto.IV);

            Console.WriteLine("Start: {0}", plainText);
            Console.WriteLine("Encrypted: {0}", encryptedText);
            Console.WriteLine("Encrypted Base64: {0}", encryptedTextBase64);
            Console.WriteLine("From Base64 To AES Encypted Text: {0}", fromBase64ToEncryptedText);
            Console.WriteLine("Decrypted: {0}", decrypted);

            Console.WriteLine("Decrypted From Encode and then Decode Base64 Text: {0}", decryptedFromB64EncodedDecoded);

        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception: {0}", ex.Message);
        }

        Console.ReadLine();
    }

public static string decrypt (byte[] textToDecrypt, byte[] key, byte[] IV)
    {
        RijndaelManaged crypto = new RijndaelManaged();
        MemoryStream stream = new MemoryStream(textToDecrypt) ;
        ICryptoTransform decryptor = null;
        CryptoStream cryptoStream = null;
        StreamReader readStream = null;

        string text = string.Empty;

        try
        {
            crypto.Key = key;
            crypto.IV = IV;
            crypto.Padding = PaddingMode.None;

            decryptor = crypto.CreateDecryptor(crypto.Key, crypto.IV);
            cryptoStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read);
            //cryptoStream.Read(textToDecrypt, 0, textToDecrypt.Length);
            readStream = new StreamReader(cryptoStream);
            text = readStream.ReadToEnd();
            cryptoStream.Close();

            byte[] decodedValue = stream.ToArray();

            return text;
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            if (crypto != null)
            {
                crypto.Clear();
            }
            stream.Flush();
            stream.Close();
        }
    }

public static byte[] encrypt(string text, byte[] key, byte[] IV)
    {
        RijndaelManaged crypto = null;
        MemoryStream stream = null;

        //ICryptoTransform is used to perform the actual decryption vs encryption, hash function are a version crypto transforms
        ICryptoTransform encryptor = null;
        //CryptoStream allows for encrption in memory
        CryptoStream cryptoStream = null;

        UTF8Encoding byteTransform = new UTF8Encoding();

        byte[] bytes = byteTransform.GetBytes(text);

        try
        {
            crypto = new RijndaelManaged();
            crypto.Key = key;
            crypto.IV = IV;

            stream = new MemoryStream();

            encryptor = crypto.CreateEncryptor(crypto.Key, crypto.IV);
            cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write);
            cryptoStream.Write(bytes, 0, bytes.Length);

        }
        catch (Exception)
        {

            throw;
        }
        finally
        {
            if (crypto != null)
            {
                crypto.Clear();
            }
            cryptoStream.Close();
        }

        return stream.ToArray();
    }

 public static string toBase64String(string value)
    {
        UTF8Encoding UTF = new UTF8Encoding();
        byte[] myarray =  UTF.GetBytes(value);
        return Convert.ToBase64String(myarray);
    }

    public static byte[] fromBase64String(string mystring)
    {
        //UTF8Encoding UTF = new UTF8Encoding();
        //byte[] myarray = UTF.GetBytes(value);
        return Convert.FromBase64String(mystring);
    }
Joseph Freeman
  • 1,644
  • 4
  • 24
  • 43

2 Answers2

1

I don't know how you're decrypting but before you decrypt, you should convert the base 64 string to a byte array before sending it into the decryption.

byte[] encryptedStringAsBytes = Convert.FromBase64String(base64EncodedEncryptedValue);

Then with the byte array you can pass to the CryptoStream via a MemoryStream.

UPDATE

I believe the issue is how you're setting up your streams

            using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
            {
                rijndaelManaged.Padding = paddingMode;
                rijndaelManaged.Key     = key;
                rijndaelManaged.IV      = initVector;

                MemoryStream memoryStream = null;
                try
                {
                    memoryStream = new MemoryStream(valueToDecrypt);
                    using (ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor())
                    {
                        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Read))
                        {
                            using (StreamReader streamReader = new StreamReader(cryptoStream))
                            {
                                return streamReader.ReadToEnd();                       
                            }
                        }
                    }
                }
                finally
                {
                    if (memoryStream != null)
                        memoryStream.Dispose();
                }
            }    

UPDATE 2

This is how you should basically perform the steps.

To encrypt

  1. Encode your plain text string using the Encoding.GetBytes(stringToEncrypt)
  2. pass the byte[] into the crypto API (via memory stream, etc.)
  3. get the bytes from the encrypted stream and encode the results as Base64

To Decrypt (do the reverse)

  1. Convert the base64 encoded string to bytes using Convert.FromBase64String(base64EncodedEncryptedValue)
  2. pass that byte array into your decryption function above
Jim
  • 4,910
  • 4
  • 32
  • 50
  • 1
    Hey :) That's exactly what I'm doing. I'll update with the decrypting code so you can take a look at it, I could be doing something wrong lol. – Joseph Freeman Dec 02 '15 at 18:20
  • Ok cool! I'll give that a shot! I'll let you know if that works here shortly. – Joseph Freeman Dec 02 '15 at 18:32
  • In actualality, I prefer to return a SecureString.or byte[] – Jim Dec 02 '15 at 18:37
  • I noticed that you did not pass the key and initialization vector into CreateDecryptor, is that not necessary? – Joseph Freeman Dec 02 '15 at 18:47
  • So I just finished refactoring my streams, and I'm getting the same thing, when decoding the base64 string so that it is the original aes encrypted string and the decrypting that string it give me a bunch of junk :( – Joseph Freeman Dec 02 '15 at 19:01
  • Must be the encryption side then. – Jim Dec 02 '15 at 19:12
  • I do use the key and init vector, just after the using (RijndaelManaged rijndaelManaged = new RijndaelManaged()) – Jim Dec 02 '15 at 19:14
  • Ah, so don't have to pass those into the rijndaelManaged.CreateDecryptor(), that's what was doing. Seems to work either way :) – Joseph Freeman Dec 02 '15 at 19:16
  • That's exactly what I doing :) I have to missing something for this not to be working. Should be using ASCII.GetBytes or UTF8.GetBytes? As of now I'm using ASCII.GetBytes. – Joseph Freeman Dec 02 '15 at 19:30
1

Try:

encryptedBytes2 = Encoding.ASCII.GetBytes(encryptedText);

Based on your comment. The bytes are just that bytes, so in order to decrypt the ciphertext you need to undo any encoding or series of encodings you have done.

If you really want to go from Encrypted Bytes -> Base64String -> ASCII string -> then decrypt that ASCII string? you would need to base64 decode the ascii string then convert that string to bytes using

Encoding.ASCII.GetBytes(yourdecodedstring); 

Note that base 64 decoding is not the same as using Convert.FromBase84String.

j-u-s-t-i-n
  • 1,402
  • 1
  • 10
  • 16
  • That would defeat the purpose what I trying to accomplish, which is to encode the AES to a base64 string and then decode the base64 to the AES encrypted string and then decrypt that. – Joseph Freeman Dec 02 '15 at 19:14
  • So Encrypted Bytes -> Base64String -> ASCII string -> then decrypt that ASCII string? – j-u-s-t-i-n Dec 02 '15 at 19:22
  • 1
    Yes :) but for whatever reason when i get the last step of decrypting the string give returns junk string instead of "foo bar". – Joseph Freeman Dec 02 '15 at 19:24
  • In order to decrypt you need to pass the exact same bytes back. You can't go from base64 to ASCII and then back to Base64 the way you are doing it. – j-u-s-t-i-n Dec 02 '15 at 19:25
  • For example a in ASCII, is YQ== in base 64. If you then make the base64 string ASCII and base64 encode that you will get WVE9PQ==. So you can't just get the bytes from WVE9PQ== and expect to decrypt it. Does that make sense? – j-u-s-t-i-n Dec 02 '15 at 19:30
  • Ahhhhhhhh, good good. One things I noticed that the second byte[] was larger than the original. I managed to correct this using Encoding.ASCII.GetString and that gave the same number of bytes, but just because they are the same number of bytes doesn't mean the data is the same. I didn't think about.....So my question now is how get achieve this....... – Joseph Freeman Dec 02 '15 at 19:35
  • Can I ask why you need to convert it to ASCII? There might be an easier solution. – j-u-s-t-i-n Dec 02 '15 at 19:36
  • I really don't need to convert to ASCII, if there is a better solution then by all means spill the beans lol :) – Joseph Freeman Dec 02 '15 at 19:43
  • Then doesn't my original answer solve the problem? encryptedBytes2 = Encoding.ASCII.GetBytes(encryptedText); You successfully encrypted and decrypted the text "foo bar". If you want those bytes stored in ASCII or base64 just convert them, but be sure to convert them back before decryption. – j-u-s-t-i-n Dec 02 '15 at 19:51
  • Yes, I totally had screwed my encryption, decryption, encoding, decoding flow. When you mentioned that I looked at my code again and was like "why am I doing that......stupid" lol. Thanks for your insight man!!! You were really helpful! – Joseph Freeman Dec 02 '15 at 19:54
  • Np - why did you mark the other answer as the one that fixed your issue though? – j-u-s-t-i-n Dec 02 '15 at 19:56
  • 1
    Well his suggest was a lot cleaner then what I was doing, it wasn't wrong. Your answer helped solve my decoding issues. So I wanted both you guys to get credit for good answers and suggestions :) – Joseph Freeman Dec 02 '15 at 21:53