0

Steps to reproduce the unexpected result:

  1. Using http://aesencryption.net/ I encrypt the text HappyCoding with yecpPqAJ+PnBMtggWVz42WME3TjhG313OhvBuUJOFtc= as the key and 256-Bit option chosen in the drop-down. I receive Lox/sfjNyXOzP9ZE8Fjj9REcuB+iJ1EXXuNjf2du29c= as a result.
  2. I then run it through the Decrypt function in my code:

    var testAesString = "Lox/sfjNyXOzP9ZE8Fjj9REcuB+iJ1EXXuNjf2du29c=";
    var decryptedString = Decrypt(testAesString, key);
    

    and receive "�ГYC���{R\u0017V��@\u0013�NH�$�|�\u001a)˪n�mp" instead of "HappyCoding"

The code for the Decrypt function is below:

private static string Decrypt(string stringCypher_Text, string stringKey)
        {
            Byte[] Key = Convert.FromBase64String(stringKey);

            Byte[] Cypher_Text = Convert.FromBase64String(stringCypher_Text);

            RijndaelManaged Crypto = null;
            MemoryStream MemStream = null;
            ICryptoTransform Decryptor = null;
            CryptoStream Crypto_Stream = null;
            StreamReader Stream_Read = null;
            string Plain_Text;

            try
            {
                Crypto = new RijndaelManaged();
                Crypto.Padding = PaddingMode.Zeros;
                Crypto.Key = Key;
                Crypto.BlockSize = 256;
                Crypto.Mode = CipherMode.ECB;
                Crypto.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

                Decryptor = Crypto.CreateDecryptor(Crypto.Key, Crypto.IV);
                MemStream = new MemoryStream(Cypher_Text);
                Crypto_Stream = new CryptoStream(MemStream, Decryptor, CryptoStreamMode.Read);
                Stream_Read = new StreamReader(Crypto_Stream);
                Plain_Text = Stream_Read.ReadToEnd();
            }
            finally
            {
                if (Crypto != null)
                    Crypto.Clear();

                MemStream.Flush();
                MemStream.Close();
            }
            return Plain_Text;
        }

I am not receiving any errors. I am receiving an unexpected result. I don't know how to approach this in regards to testing it further. My thought is maybe the website I am using to receive the encrypted values in the first place is using different settings etc.

Any direction on how to test and/or resolve is appreciated.

HappyCoding
  • 641
  • 16
  • 36
  • you have to decode the raw stream using an encoder such as utf8 or ascii. – Daniel A. White Feb 02 '16 at 21:04
  • You're generating a new Initialization Vector - shouldn't it be the same as the one used to do the encryption? – Tim Feb 02 '16 at 21:04
  • @Tim the website I mentioned doesn't have a parameter for IV. I am unsure of the initial IV used to do the encryption. – HappyCoding Feb 02 '16 at 21:08
  • Those look like Base64 encoded strings. Try converting the Base64 string to an array of bytes, and decode that array of bytes. – Berin Loritsch Feb 02 '16 at 21:09
  • 1
    The site http://www.aesencryption.net/ doesn't seem to expect the key to be base64-encoded. – Ctx Feb 02 '16 at 21:09
  • 2
    Possible duplicate of [What C# AES encryption options to use so result can be decrypted on a public web site?](http://stackoverflow.com/questions/28217904/what-c-sharp-aes-encryption-options-to-use-so-result-can-be-decrypted-on-a-publi) – Artjom B. Feb 02 '16 at 21:21
  • Using the key and plain text from your example I get the exact same cipher text, so they use the same IV every time but don't mention it anywhere. You could try mailing the guy who runs the site or finding some other site that does provide the IV with the example. You could try guessing a few obvious choices like a byte array of all zeroes or use the key as IV as well but if those don't work then you're out of luck. – Mark Feb 02 '16 at 21:23
  • @Mark Do you believe the IV is to blame primarily? – HappyCoding Feb 02 '16 at 21:53
  • @HappyCoding: Yes. Using the wrong IV makes your result "almost as wrong" as using the wrong key. When decrypting (symmetric) you need all settings to be the same as they were when encrypting. So same key but also same IV, same PaddingMode and same block cipher Mode. – Mark Feb 02 '16 at 21:59
  • @DanielA.White How would I go about doing this? If you don't want to provide code, that is fine. Would you point me to documentation? – HappyCoding Feb 02 '16 at 22:00
  • @HappyCoding The problem also lies in the fact that the site you're using doesn't explicitly state some of those values. I think the link provided by Artjom B has guessed the correct IV, PaddingMode and Mode that http://aesencryption.net/ is using. – Mark Feb 02 '16 at 22:04
  • @Mark and @Artjom B. Yes I have updated my RijndaelManaged values to match that of the posted link. Since then the decryptedString value is now `"�ГYC���{R\u0017V��@\u0013�NH�$�|�\u001a)˪n�mp"` – HappyCoding Feb 02 '16 at 22:08
  • @Mark what makes you think that the site uses cbc or similar? It probably simply uses ecb without an IV at all – Ctx Feb 02 '16 at 22:50
  • @Ctx Most likely but the problem is that there's no telling _what_ the site does. Not even how it uses the key you enter (as you've noted yourself as well). So it's better to just forget it and look at a different example altogether. – Mark Feb 02 '16 at 22:57
  • @HappyCoding Got it to work. Added a new answer. – Mark Feb 03 '16 at 00:07

2 Answers2

2

Played around with it a bit more and got the following to work. The site appears to just grab the first 32 bytes of whatever string you use as key.

    public static string DecryptLikeSite(string base64EncodedCipherText, string key)
    {
        using (var alg = new RijndaelManaged())
        {
            alg.BlockSize = 256;
            alg.Key = System.Text.Encoding.ASCII.GetBytes(key).Take(32).ToArray();
            alg.Mode = CipherMode.ECB;
            alg.Padding = PaddingMode.Zeros;
            alg.IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

            var cipherText = Convert.FromBase64String(base64EncodedCipherText);

            using (ICryptoTransform decryptor = alg.CreateDecryptor())
            {
                using (var ms = new MemoryStream(cipherText))
                {
                    using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                    {
                        using (var sr = new StreamReader(cs))
                        {
                            return sr.ReadToEnd().Replace("\0", string.Empty);
                        }
                    }
                }
            }
        }
    }

    public static void Test()
    {
        string key = "yecpPqAJ+PnBMtggWVz42WME3TjhG313OhvBuUJOFtc=";
        string expectedPlainText = "HappyCoding";

        string base64EncodedSiteCipherText = "Lox/sfjNyXOzP9ZE8Fjj9REcuB+iJ1EXXuNjf2du29c=";
        string plainText = DecryptLikeSite(base64EncodedSiteCipherText, key);

        bool success = expectedPlainText == plainText;
    }
Mark
  • 1,360
  • 1
  • 8
  • 14
0

Because the cipher text is two blocks, but the plain text is less than one block, I guess that the first block is an IV.

Try using the first 16 bytes of the cipher text as an IV in CBC mode, and decrypt the next 16 bytes.

erickson
  • 265,237
  • 58
  • 395
  • 493