Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

350
Views
Encryption with Crypto in Node.js does not give expected result

I have an old embedded device that expects an encrypted password with a given cipher, key and IV. An existing application written in .NET framework creates an AES-128-CBC encrypted string, and I'm re-writing this in Node.js using the Crypto library.

However, when I encrypt a string with the same key and IV in Node.js, the output is not the same as in .NET. I've double checked the encryption with online tools, and they yield the same result as .NET, so Node.js Crypto is the odd one out.

The C# code for .NET (the key and IV has been substituted for demonstration purpose):

byte[] encrypted;
        
        using (AesManaged aes = new AesManaged())
        {
            aes.Mode = CipherMode.CBC;
            aes.Padding = PaddingMode.Zeros;
            aes.Key = new byte[] { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
            aes.IV = new byte[] { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 };

            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write("admin");
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        } 
        return encrypted;

This gives the Base64 string gE1twb8LV/44oO/6UKwwCg==. I've tested the same cipher, key and IV with online tools, and they give the same output.

My Node.js code:

const crypto = require('crypto');

const key = Buffer.from('00112233445566778899aabbccddeeff', 'hex');
const iv = Buffer.from('aabbccddeeff00112233445566778899', 'hex');

const plaintext = 'admin';
var cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
cipher.update(Buffer.from('admin'));
var encrypted = cipher.final().toString('base64');

This gives the Base64 string 4TT9E4WDH/TmlKjJdVFeHQ==.

I have tried everything I can think of with no luck. I've noticed that the .NET code specifies a zero-padding, but I've not been able to find a way to set this in the Node.js Crypto. I'm guessing this is probably why it doesn't give the same output.

Anyone know how to specify zero-padding in Node.js Crypto?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

As you have already noticed, the paddings do not match. In the C# code zero padding is specified, in the NodeJS code PKCS#7 is used by default. Since the crypto module of NodeJS does not support zero padding, you have to implement this yourself and disable the default padding.

Also, input and output encoding must be defined for the update() and final() calls and the portions must be concatenated. In the following NodeJS code, UTF-8 is specified as input encoding and Base64 as output encoding:

const crypto = require('crypto');

const key = Buffer.from('00112233445566778899aabbccddeeff', 'hex');
const iv = Buffer.from('aabbccddeeff00112233445566778899', 'hex');

const plaintext = 'admin';
var cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
cipher.setAutoPadding(false); // Disable default PKCS#7 padding
var paddedPlaintext = zeroPad(plaintext, 16); // Zero pad plaintext
var encrypted = cipher.update(paddedPlaintext, 'utf8', 'base64'); // Specify input-/outputencoding
encrypted += cipher.final('base64'); // Specify outputencoding and concatenate
console.log(encrypted); // gE1twb8LV/44oO/6UKwwCg==

function zeroPad(text, bs){
    var padLength = text.length;
    if (text.length % bs > 0){
      padLength += bs - text.length % bs;
    }
    return text.padEnd(padLength, '\0');
}

with the output:

gE1twb8LV/44oO/6UKwwCg==

which matches the output of the C# code.


Note that a static IV is insecure. It is more secure to use a randomly generated IV for each encryption. For testing purposes, of course, this is fine.
Also, zero padding is unreliable. A better choice is PKCS#7 padding (which is the crypto default).

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!