Shubham
Shubham

Reputation: 135

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.

Upvotes: 4

Views: 6791

Answers (2)

John Scott
John Scott

Reputation: 85

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)

}

Upvotes: 0

Topaco
Topaco

Reputation: 49131

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.

Upvotes: 8

Related Questions