4

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.

4
  • 1
    You know about https right..? Commented Aug 26, 2020 at 13:21
  • 1
    @MikeOne I know a little bit about it, but In this case, I want to hide that data in my browser's network tab so I am encrypting it. Commented Aug 26, 2020 at 13:47
  • 1
    Your ASP code is using AES in mode CBC that involves an initialization vector ('iv'). On Angular the same iv has to be used for decryption but I do not see any 'iv' ? Commented Aug 26, 2020 at 17:33
  • @MichaelFehr I had added IV in my code but still, the error was the same so I removed it. CryptoJS.AES.decrypt(encrypted, key, { iv: iv, padding: CryptoJS.pad.Pkcs7, mode: CryptoJS.mode.CBC } Commented Aug 26, 2020 at 17:48

2 Answers 2

8

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank You so much. This code worked perfectly. I spent too much time on this problem. Thank you for clearing concepts! Thanks!
0

Just a quick update on this as it's a few years old (but still very helpful!) I've made one small change to @Topaco. CryptoJS doesn't use .create, so instead you need init a new WordArray().

decryptString(key: string, ciphertextB64: string) {                              
    // Base64 encoded ciphertext, 32 bytes string as key
    var keyBytes = CryptoJS.enc.Utf8.parse(key);                      // Convert into WordArray (using Utf8)
    var iv = new CryptoJS.lib.WordArray([0x00, 0x00, 0x00, 0x00]);    // Use zero vector as IV
    var decrypted = CryptoJS.AES.decrypt(ciphertextB64, keyBytes, { iv: iv }); // By default: CBC, PKCS7 
    return decrypted.toString(CryptoJS.enc.Utf8);                       // Convert into string (using Utf8)

}

2 Comments

...CryptoJS doesn't use .create, so instead you need init a new WordArray()... This is not true in this generality! create() is supported as you can verify with the executable code in the other answer for v4.0.0 (or here jsfiddle.net/L8gb5z92 for the latest version v4.1.1) and in the source code. That it doesn't work for you is probably an environment specific (angular?) issue.
Thanks for clarifying @Topaco... you are correct .... I AM using the TS version (npm crypto-ts) and I think the TS version is slightly different and that's why I wasn't seeing it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.