title: Create 16 byte key for AES Encryption from Salt and Password in Node JS Crypto
body: <p>I'm trying to match an AES 256 CBC encryption implemented in C# by using node JS crypto module.</p>
  
  <p>This is my C# code</p>
  
  <pre><code>using System;
  using System.Security.Cryptography; 
  using System.Text;
  public class Program
  {
      public static void Main()
      {
          Console.WriteLine(EncryptExt("Hello World"));
          Console.WriteLine(DecryptExt(EncryptExt("Hello World")));
      }
  
      public static string EncryptExt(string raw)
  
          {
  
              using (var csp = new AesCryptoServiceProvider())
  
              {
  
                  ICryptoTransform e = GetCryptoTransformExt(csp, true);
  
                  byte[] inputBuffer = Encoding.UTF8.GetBytes(raw);
  
                  byte[] output = e.TransformFinalBlock(inputBuffer, 0, inputBuffer.Length);
  
  
  
                  string encrypted = Convert.ToBase64String(output);
  
  
  
                  return encrypted;
  
              }
  
          }
  
  
  
          public static string DecryptExt(string encrypted)
  
          {
  
              using (var csp = new AesCryptoServiceProvider())
  
              {
  
                  var d = GetCryptoTransformExt(csp, false);
  
                  byte[] output = Convert.FromBase64String(encrypted);
  
                  byte[] decryptedOutput = d.TransformFinalBlock(output, 0, output.Length);
  
  
  
                  string decypted = Encoding.UTF8.GetString(decryptedOutput);
  
                  return decypted;
  
              }
  
          }
  
  
  
          private static ICryptoTransform GetCryptoTransformExt(AesCryptoServiceProvider csp, bool encrypting)
  
          {
  
              csp.Mode = CipherMode.CBC;
  
             csp.Padding = PaddingMode.PKCS7;
  
              var passWord = Convert.ToString("AvbSkj3BVbf4o6mdlAofDp0/SD0susEWo0pKdmqas");
  
              var salt = Convert.ToString("ABj4PQgf3j5gblQ0iDp0/Gb07ukQWo0a");
  
  
  
              String iv = Convert.ToString("aAB1jhPQ89o=f619");
  
  
  
              var spec = new Rfc2898DeriveBytes(Encoding.UTF8.GetBytes(passWord), Encoding.UTF8.GetBytes(salt), 65536);
  
              byte[] key = spec.GetBytes(16);
  
  
  
  
  
              csp.IV = Encoding.UTF8.GetBytes(iv);
  
              csp.Key = key;
  
              if (encrypting)
  
              {
  
                  return csp.CreateEncryptor();
  
              }
  
              return csp.CreateDecryptor();
  
          }
  
  }
  </code></pre>
  
  <p>And this is my Node JS implementation</p>
  
  <pre><code>const crypto = require('crypto'),
    algorithm = 'aes-128-cbc',
    password = 'AvbSkj3BVbf4o6mdlAofDp0/SD0susEWo0pKdmqas',
    salt = 'ABj4PQgf3j5gblQ0iDp0/Gb07ukQWo0a',
    iv = 'aAB1jhPQ89o=f619',
    inputEncoding = 'utf8',
    outputEncoding = 'base64';
  
  
   function encrypt(text) {
    let cipher = crypto.createCipheriv(algorithm,createHashPassword(), iv);
    let encrypted = cipher.update(text, inputEncoding, outputEncoding)
    encrypted += cipher.final(outputEncoding);
    return encrypted;
  }
  
  function createHashPassword(){
      let nodeCrypto = crypto.pbkdf2Sync(Buffer.from(password), Buffer.from(salt), 65536, 16, 'sha1');
  
      return nodeCrypto || nodeCrypto.toString('hex');
  };
  
  function decrypt(encrypted) {
    let decipher = crypto.createDecipheriv(algorithm, Buffer.from(createHashPassword(),"hex"), iv)
    let dec = decipher.update(encrypted, outputEncoding, inputEncoding)
    dec += decipher.final(inputEncoding);
    return dec;
  }
  
  console.log(encrypt('Hello World'));
  console.log(decrypt(encrypt('Hello World')));
  </code></pre>
  
  <p>The encrypted data from both this  options are coming different hence, not able to work this out.</p>
  
  <p>So far what I have seen is,</p>
  
  <ul>
  <li>node crypto createCipheriv method takes only 32 byte buffer and if I
  pass it a 16 byte buffer it says, invalid length. </li>
  <li>If I convert the 16 byte key to hex encoded string, the encrypted value changes and does not match with the C# implementation.</li>
  <li>I can't change the C# implementation as its already in production and been used by multiple applications.</li>
  <li>So there seems to be an issue with generating key from salt and password in node js, matching what is done in C# and I'm not able to figure that out.</li>
  </ul>
  
  <p>Code can be tested in the below link:
  C# Implementation: <a href="https://dotnetfiddle.net/bClrpW" rel="nofollow noreferrer">https://dotnetfiddle.net/bClrpW</a>
  Node JS Implementation: <a href="https://runkit.com/a-vi-nash/5c062544509d8200156f6111" rel="nofollow noreferrer">https://runkit.com/a-vi-nash/5c062544509d8200156f6111</a></p>