Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AES encryption in Node JS and C# gives different results

I have a use case where the text has to be encoded and sent using the AES 256 algorithm. The client-side code is in C# which would be decrypting the code.

Encryption code in JS:

const crypto = require('crypto');
  algorithm = 'aes-256-cbc',
  secret = '1234567890123456',
  keystring = crypto.createHash('sha256').update(String(secret)).digest('base64').substr(0, 16);
  iv = crypto.createHash('sha256').update(String(secret)).digest('base64').substr(0, 16);
  inputEncoding = 'utf8',
  outputEncoding = 'base64';


function encrypt(text) {
  let cipher = crypto.createCipheriv('aes-256-cbc', keystring, iv);
  let encrypted = cipher.update(text, inputEncoding, outputEncoding)
  encrypted += cipher.final(outputEncoding);
  return encrypted;
}

Updated code used in the client side:

var keybytes = Encoding.UTF8.GetBytes(passwordKey);
var iv = Encoding.UTF8.GetBytes(passwordKey);

private byte[] EncryptStringToBytes(string plainText, byte[] key, byte[] iv)
        {
            try
            {
                // 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("key");
                }
                byte[] encrypted;
                // Create a RijndaelManaged object  
                // with the specified key and IV.  
                using (var rijAlg = new RijndaelManaged())
                {
                    rijAlg.Mode = CipherMode.CBC;
                    rijAlg.Padding = PaddingMode.PKCS7;
                    rijAlg.FeedbackSize = 128;

                    rijAlg.Key = key;
                    rijAlg.IV = iv;

                    // Create a decrytor to perform the stream transform.  
                    var encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

                    // Create the streams used for encryption.  
                    using (var msEncrypt = new MemoryStream())
                    {
                        using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                        {
                            using (var swEncrypt = new StreamWriter(csEncrypt))
                            {
                                //Write all data to the stream.  
                                swEncrypt.Write(plainText);
                            }
                            encrypted = msEncrypt.ToArray();
                        }
                    }
                }
                // Return the encrypted bytes from the memory stream.  
                return encrypted;
            }
            catch (Exception ex)
            {
                throw ex;
                //LoggerCS.logError("Utility", "EncryptStringToBytes", JsonConvert.SerializeObject(null), ex.ToString(), ex.StackTrace);
            }
            return null;
        }

The keyString and IV value used are same in C# and is encrypted using Utf8. Looking for the equivalent operation in Node JS.

like image 947
Suchetha B Avatar asked Jun 18 '20 09:06

Suchetha B


People also ask

What is AES encryption with example?

The size of each block is usually measured in bits. AES, for example, is 128 bits long. Meaning, AES will operate on 128 bits of plaintext to produce 128 bits of ciphertext. Like almost all modern encryption algorithms, AES requires the use of secret keys during the encryption and decrypt processes.

What are the 4 steps of AES algorithm?

To review the overall structure of AES and to focus particularly on the four steps used in each round of AES: (1) byte substitution, (2) shift rows, (3) mix columns, and (4) add round key.

How do you encrypt data in node JS?

Using Clean architecture for Node.NodeJS provides inbuilt library crypto to encrypt and decrypt data in NodeJS. We can use this library to encrypt data of any type. You can do the cryptographic operations on a string, buffer, and even a stream of data.

Is AES better than PGP?

When you are considering which encryption to use for your sensitive information, choose whichever will suit your needs best: AES is fast and works best in closed systems and large databases. PGP should be used when sharing information across an open network, but it can be slower and works better for individual files.


1 Answers

TLDR;

You're using a different IV and algorithm (AES-128 vs AES-256) so you will get different results...

You will need to use the same IV as well as the same key and algorithm if you want to get identical results. This would be an anti-pattern (i.e. don't do this)! Check John's comment about how you're ignoring the algorithm variable in your code, as at a quick glance this and the different IV are responsible for why you're getting different results.

Longer Answer;

1) You actually want it so that the same message (plain text) encrypted with the same key does not always produce the same encrypted result (cipher text). Otherwise any party that is eavesdropping will always know when a duplicate message has been sent again.

2) The initialization vector (IV) is used to provide randomness so that the same plain text does not always result in the same cipher text when a given key is used.

3) This means that to decrypt a message you need to know not only the key but also the IV.

4) The IV should be random and not deterministically derived from the key, otherwise every use of the same key will have the same IV and thus each time the same plain text is encrypted the same cipher text would result. (Leaving you vulnerable to eavesdroppers observing the results of a given message being received and beginning to determine the meaning of the message).

Have a look at the answers to this question AES Encryption - Key versus IV and also this Wikipedia entry http://en.wikipedia.org/wiki/Initialization_vector for more info.

like image 185
Alex Hague Avatar answered Oct 04 '22 10:10

Alex Hague