5 Replies - 50556 Views - Last Post: 11 September 2013 - 08:12 AM Rate Topic: -----

#1 joaocabaco   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 31-August 13

AES encrypt in Javascript and decrypt in C#

Posted 04 September 2013 - 03:40 PM

Hello,

I'm having a hard time decrypting in C# data that was encrypted on client-side using CryptoJS.

Javascript Code:

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script>

    var key = CryptoJS.enc.Utf8.parse('AMINHAKEYTEM32NYTES1234567891234');
    var iv = CryptoJS.enc.Utf8.parse('7061737323313233');
    var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse("It works"), "Secret Passphrase", key, 
 { 
     keySize: 128,
     iv: iv, 
     mode: CryptoJS.mode.CBC,
     padding: CryptoJS.pad.Pkcs7 
 }); 

    </script>





Results from javascript:

//////////////DATA FROM CRYPTOJS
//enc:U2FsdGVkX19cNNeEUTEspBKuiUus3EFrkTElHDyZd54=
//key:48390e5076d5f67516b2fd776d1f799b4a61972b2fcaf27d362802c00a00c9c7
//salt:5c34d78451312ca4
//iv:c3ed8b19df64a88048bd30e7f82db106
//

Code C#:


//////////////DATA FROM CRYPTOJS
//enc:U2FsdGVkX19cNNeEUTEspBKuiUus3EFrkTElHDyZd54=
//key:48390e5076d5f67516b2fd776d1f799b4a61972b2fcaf27d362802c00a00c9c7
//salt:5c34d78451312ca4
//iv:c3ed8b19df64a88048bd30e7f82db106


        string encrypted = "U2FsdGVkX19cNNeEUTEspBKuiUus3EFrkTElHDyZd54=";

        string decrypted = Decrypt<AesManaged>(encrypted, "Secret Passphrase", "5c34d78451312ca4");


        public static string Decrypt<T>(string text, string password, string salt)
           where T : SymmetricAlgorithm, new()
        {
            DeriveBytes rgb = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt));

            SymmetricAlgorithm algorithm = new T();

            algorithm.Key = Encoding.UTF8.GetBytes("AMINHAKEYTEM32NYTES1234567891234");
            algorithm.IV = Encoding.UTF8.GetBytes("7061737323313233");

            byte[] rgbKey = rgb.GetBytes(algorithm.KeySize >> 3);
            byte[] rgbIV = rgb.GetBytes(algorithm.BlockSize >> 3);

            ICryptoTransform transform = algorithm.CreateDecryptor(rgbKey, rgbIV);

            using (MemoryStream buffer = new MemoryStream(Convert.FromBase64String(text)))
            {
                using (CryptoStream stream = new CryptoStream(buffer, transform, CryptoStreamMode.Read))
                {
                    using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
                    {
                        return reader.ReadToEnd();
                    }
                }
            }
        }




Error Printscreens:
img 1
img2
img3

Is This A Good Question/Topic? 0
  • +

Replies To: AES encrypt in Javascript and decrypt in C#

#2 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7053
  • View blog
  • Posts: 23,973
  • Joined: 05-May 12

Re: AES encrypt in Javascript and decrypt in C#

Posted 04 September 2013 - 09:54 PM

I recommend first getting roundtripping working C# to C#. Only once you've got that working, then move on getting the ciphertext from Javascript and decrypting in C#.

Right now, just glancing at your code, I'm wondering if your rgbKey and rgbIV are matching up with the key and iv that you got from Javascript.
Was This Post Helpful? 0
  • +
  • -

#3 joaocabaco   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 31-August 13

Re: AES encrypt in Javascript and decrypt in C#

Posted 05 September 2013 - 06:52 AM

View PostSkydiver, on 04 September 2013 - 09:54 PM, said:

I recommend first getting roundtripping working C# to C#. Only once you've got that working, then move on getting the ciphertext from Javascript and decrypting in C#.

Right now, just glancing at your code, I'm wondering if your rgbKey and rgbIV are matching up with the key and iv that you got from Javascript.


Yes, it works C# to C#.
I can not find where is the error I think may be related to key / iv or CryptoStream stream or StreamReader reader, then generated the error "padding"

Can you help?

Thank you.
Was This Post Helpful? 0
  • +
  • -

#4 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7053
  • View blog
  • Posts: 23,973
  • Joined: 05-May 12

Re: AES encrypt in Javascript and decrypt in C#

Posted 05 September 2013 - 07:42 PM

Show us your C# to C# implementation. Most people accidentally use the same instance of the SymmetricAlgorithm between encryption and decryption so things magically work because some settings get carried over. When you have then construct new instance for each operation, they then discover that they missed some settings.

As an aside, with the original code you posted, try swapping out AesManaged with the AesCryptoServiceProvider. You've probably already done searches on Google about AesManaged and getting the "padding is invalid" exception. Some of them have had success swapping implementations.
Was This Post Helpful? 0
  • +
  • -

#5 joaocabaco   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 31-August 13

Re: AES encrypt in Javascript and decrypt in C#

Posted 11 September 2013 - 06:57 AM

View PostSkydiver, on 05 September 2013 - 07:42 PM, said:

Show us your C# to C# implementation. Most people accidentally use the same instance of the SymmetricAlgorithm between encryption and decryption so things magically work because some settings get carried over. When you have then construct new instance for each operation, they then discover that they missed some settings.

As an aside, with the original code you posted, try swapping out AesManaged with the AesCryptoServiceProvider. You've probably already done searches on Google about AesManaged and getting the "padding is invalid" exception. Some of them have had success swapping implementations.


Resolved!! =)

Thanks for the help!

public string OpenSSLEncrypt(string plainText, string passphrase)
        {
            // generate salt
            byte[] key, iv;
            byte[] salt = new byte[8];
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetNonZeroBytes(salt);
            DeriveKeyAndIV(passphrase, salt, out key, out iv);
            // encrypt bytes
            byte[] encryptedBytes = EncryptStringToBytesAes(plainText, key, iv);
            // add salt as first 8 bytes
            byte[] encryptedBytesWithSalt = new byte[salt.Length + encryptedBytes.Length + 8];
            Buffer.BlockCopy(Encoding.ASCII.GetBytes("Salted__"), 0, encryptedBytesWithSalt, 0, 8);
            Buffer.BlockCopy(salt, 0, encryptedBytesWithSalt, 8, salt.Length);
            Buffer.BlockCopy(encryptedBytes, 0, encryptedBytesWithSalt, salt.Length + 8, encryptedBytes.Length);
            // base64 encode
            return Convert.ToBase64String(encryptedBytesWithSalt);
        }

        public string OpenSSLDecrypt(string encrypted, string passphrase)
        {
            // base 64 decode
            byte[] encryptedBytesWithSalt = Convert.FromBase64String(encrypted);
            // extract salt (first 8 bytes of encrypted)
            byte[] salt = new byte[8];
            byte[] encryptedBytes = new byte[encryptedBytesWithSalt.Length - salt.Length - 8];
            Buffer.BlockCopy(encryptedBytesWithSalt, 8, salt, 0, salt.Length);
            Buffer.BlockCopy(encryptedBytesWithSalt, salt.Length + 8, encryptedBytes, 0, encryptedBytes.Length);
            // get key and iv
            byte[] key, iv;
            DeriveKeyAndIV(passphrase, salt, out key, out iv);
            return DecryptStringFromBytesAes(encryptedBytes, key, iv);
        }

        private static void DeriveKeyAndIV(string passphrase, byte[] salt, out byte[] key, out byte[] iv)
        {
            // generate key and iv
            List<byte> concatenatedHashes = new List<byte>(48);

            byte[] password = Encoding.UTF8.GetBytes(passphrase);
            byte[] currentHash = new byte[0];
            MD5 md5 = MD5.Create();
            bool enoughBytesForKey = false;
            // See http://www.openssl.org/docs/crypto/EVP_BytesToKey.html#KEY_DERIVATION_ALGORITHM
            while (!enoughBytesForKey)
            {
                int preHashLength = currentHash.Length + password.Length + salt.Length;
                byte[] preHash = new byte[preHashLength];

                Buffer.BlockCopy(currentHash, 0, preHash, 0, currentHash.Length);
                Buffer.BlockCopy(password, 0, preHash, currentHash.Length, password.Length);
                Buffer.BlockCopy(salt, 0, preHash, currentHash.Length + password.Length, salt.Length);

                currentHash = md5.ComputeHash(preHash);
                concatenatedHashes.AddRange(currentHash);

                if (concatenatedHashes.Count >= 48)
                    enoughBytesForKey = true;
            }

            key = new byte[32];
            iv = new byte[16];
            concatenatedHashes.CopyTo(0, key, 0, 32);
            concatenatedHashes.CopyTo(32, iv, 0, 16);

            md5.Clear();
            md5 = null;
        }

        static byte[] EncryptStringToBytesAes(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("iv");

            // Declare the stream used to encrypt to an in memory
            // array of bytes.
            MemoryStream msEncrypt;

            // Declare the RijndaelManaged object
            // used to encrypt the data.
            RijndaelManaged aesAlg = null;

            try
            {
                // Create a RijndaelManaged object
                // with the specified key and IV.
                aesAlg = new RijndaelManaged { Mode = CipherMode.CBC, KeySize = 256, BlockSize = 128, Key = key, IV = iv };

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

                // Create the streams used for encryption.
                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);
                        swEncrypt.Flush();
                        swEncrypt.Close();
                    }
                }
            }
            finally
            {
                // Clear the RijndaelManaged object.
                if (aesAlg != null)
                    aesAlg.Clear();
            }

            // Return the encrypted bytes from the memory stream.
            return msEncrypt.ToArray();
        }

        static string DecryptStringFromBytesAes(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("iv");

            // Declare the RijndaelManaged object
            // used to decrypt the data.
            RijndaelManaged aesAlg = null;

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

            try
            {
                // Create a RijndaelManaged object
                // with the specified key and IV.
                aesAlg = new RijndaelManaged {Mode = CipherMode.CBC, KeySize = 256, BlockSize = 128, Key = key, 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();
                            srDecrypt.Close();
                        }
                    }
                }
            }
            finally
            {
                // Clear the RijndaelManaged object.
                if (aesAlg != null)
                    aesAlg.Clear();
            }

            return plaintext;
        }


Was This Post Helpful? 0
  • +
  • -

#6 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7053
  • View blog
  • Posts: 23,973
  • Joined: 05-May 12

Re: AES encrypt in Javascript and decrypt in C#

Posted 11 September 2013 - 08:12 AM

Congratulations!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1