Search code examples
angularasp.net-coreencryptionaescryptojs

Encryption in ASP.net Core and Decryption in Angular


I am facing problems in "Encryption in ASP.net Core and Decryption in Angular". I want to send sensitive information to FE from my BE so I am trying to add encryption and decryption.

My ASP code for encryption is :

public static string EncryptString(string key, string plainText)
        {
            byte[] iv = new byte[16];
            byte[] array;

            using (Aes aes = Aes.Create())
            {
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.IV = iv;
                aes.Padding = PaddingMode.PKCS7;
                aes.Mode = CipherMode.CBC;

                ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
                        {
                            streamWriter.Write(plainText);
                        }

                        array = memoryStream.ToArray();
                    }
                }
            }

            return Convert.ToBase64String(array);
        }

And my Angular Code for Decryption is: (Using crypto-js for decryption)

decryptData(data,key) {

    try {
      const bytes = CryptoJS.AES.decrypt(data, key); //data is encrypted string from ASP
      if (bytes.toString()) {
        return JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
      }
      return data;
    } catch (e) {
      console.log(e);
    }
  }

After running the code I am getting errors like :

Error: Malformed UTF-8 data at Object.stringify (core.js:513) at WordArray.init.toString (core.js:268) at ...

Thank you.


Solution

  • The C# code uses AES in CBC mode with a zero vector as IV and PKCS7 padding. The ciphertext is Base64 encoded. With the following sample data the following Base64 encoded ciphertext results:

    string key = "01234567890123456789012345678901"; // 32 bytes key, corresponds to AES-256
    string plaintext = "The quick brown fox jumps over the lazy dog";
    string encrypted = EncryptString(key, plaintext);
    Console.WriteLine(encrypted); // NsFJlGQScUEazmSEykVeO/lh+o2L5ykFd2hkNa5lVrHACwKfTg1pD/uYzjTfjmQO
    

    CryptoJS uses for AES the CBC mode and PKCS7 padding by default. It is important that the key in CryptoJS.AES.decrypt is passed as WordArray, otherwise it will be interpreted as password from which the key is first derived. The Base64 encoded ciphertext can be passed directly. CryptoJS.AES.decrypt returns a WordArray that must be decoded with Utf8. For the conversion from and to WordArrays CryptoJS has encoders. The following CryptoJS code allows the decryption:

    function decryptData(key, ciphertextB64) {                              // Base64 encoded ciphertext, 32 bytes string as key
        var key = CryptoJS.enc.Utf8.parse(key);                             // Convert into WordArray (using Utf8)
        var iv = CryptoJS.lib.WordArray.create([0x00, 0x00, 0x00, 0x00]);   // Use zero vector as IV
        var decrypted = CryptoJS.AES.decrypt(ciphertextB64, key, {iv: iv}); // By default: CBC, PKCS7 
        return decrypted.toString(CryptoJS.enc.Utf8);                       // Convert into string (using Utf8)
    }
        
    var ciphertextB64 = "NsFJlGQScUEazmSEykVeO/lh+o2L5ykFd2hkNa5lVrHACwKfTg1pD/uYzjTfjmQO";
    var key = "01234567890123456789012345678901";
    var decrypted = decryptData(key, ciphertextB64);
    console.log(decrypted); // The quick brown fox jumps over the lazy dog
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>

    Note that using a static IV (e.g. zero vector) is generally insecure. Usually, the IV is randomly generated during encryption and is passed to the recipient together with the ciphertext.