Search code examples
javascriptc#node.jsencryptionaes

AES encryption method in NodeJS similar to C sharp function


I have a function written in C#. Basically the function is used to generate a token on the basis of parameters like text and key.

public string Encrypt(string input, string key) {
     byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
     byte[] toEncrptArray = UTF8Encoding.UTF8.GetBytes(input);
     Aes kgen = Aes.Create("AES");
     kgen.Mode = CipherMode.ECB;
     kgen.Key = keyArray;
     ICryptoTransform cTransform = kgen.CreateEncryptor();
     byte[] resultArray = cTransform.TransformFinalBlock(toEncrptArray, 0, toEncrptArray.Length);

     return Convert.ToBase64String(resultArray, 0, resultArray.Length);
   }

I'm trying to search any same alternative for the above function in NodeJS or run this function inside the NodeJS script through any compiler.

I have tried the crypto-js module in NodeJS but got a different token string. Please suggest the alternative function or any idea about running this function inside the NodeJS script.

My Recent code in NodeJS :

First Method :

var CryptoJS = require("crypto-js");

// Encrypt
var ciphertext = CryptoJS.AES.encrypt("<input>", "<key>").toString();

Second Method :

var crypto = require('crypto'),
    algorithm = 'aes-256-ctr',
    password = '<key>';

function encrypt(text){
  var cipher = crypto.createCipher(algorithm,password)
  var crypted = cipher.update(text,'utf8','hex')
  crypted += cipher.final('hex');
  return crypted;
}

Both the method is giving different token if compared to C# function.


Solution

  • The AES algorithm used in the C# code is AES 128-bit in ECB mode.

    We can perform the same encryption in Node.js (and decrypt as well if we wish), using the following code:

    Node.js Code

    const crypto = require("crypto");
    
    function encrypt(plainText, key, outputEncoding = "base64") {
        const cipher = crypto.createCipheriv("aes-128-ecb", key, null);
        let encrypted = cipher.update(plainText, 'utf8', outputEncoding)
        encrypted += cipher.final(outputEncoding);
        return encrypted;
    }
    
    function decrypt(cipherText, key, outputEncoding = "utf8") {
        const cipher = crypto.createDecipheriv("aes-128-ecb", key, null);
        let encrypted = cipher.update(cipherText)
        encrypted += cipher.final(outputEncoding);
        return encrypted;
    }
    
    const KEY = Buffer.from("abcdefghijklmnop", "utf8");
    
    console.log("Key length (bits):", KEY.length * 8);
    const encrypted = encrypt("hello world", KEY, "base64");
    console.log("Encrypted string (base64):", encrypted);
    
    // And if we wish to decrypt as well:
    const decrypted = decrypt(Buffer.from(encrypted, "base64"), KEY, "utf8")
    console.log("Decrypted string:", decrypted);
    

    C# Code

    using System;
    using System.Text;
    using System.Security.Cryptography;
    
    public class Program
    {
        public static void Main()
        {
            Console.WriteLine("Result: " + Encrypt("hello world", "abcdefghijklmnop"));
        }
        
        public static string Encrypt(string input, string key) {
         byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
         byte[] toEncrptArray = UTF8Encoding.UTF8.GetBytes(input);
         Aes kgen = Aes.Create("AES");
         kgen.Mode = CipherMode.ECB;
         kgen.Key = keyArray;
         ICryptoTransform cTransform = kgen.CreateEncryptor();
         byte[] resultArray = cTransform.TransformFinalBlock(toEncrptArray, 0, toEncrptArray.Length);
    
         return Convert.ToBase64String(resultArray, 0, resultArray.Length);
       }
    }
    

    The results for the encryption (with plaintext and key as above) are:

    .Net: f7sSBDV0N6MOpRJLpSJL0w==
    Node.js: f7sSBDV0N6MOpRJLpSJL0w==
    

    Obviously we must not use this key in production!