Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to encrypt using crypto AES in nodejs?

We have a encryption mechanism in Go. Input will be like key= "dHRzbGNvbnNlbnR0ZWNobQ==" and text = "1234565434".

  func encrypt(key []byte, text string) (string, error) { 
     block, err := aes.NewCipher(key)
     if err != nil {
        return "", err
    }

     msg := AddPadding([]byte(text))
     ciphertext := make([]byte, aes.BlockSize+len(msg))
     iv := ciphertext[:aes.BlockSize]
     cfb := cipher.NewCFBEncrypter(block, iv)
     cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(msg))
     finalMsg := removeBase64Padding(base64.URLEncoding.EncodeToString(ciphertext))
     return finalMsg, nil
  }


 func AddPadding(src []byte) []byte {
      padding := aes.BlockSize - len(src)%aes.BlockSize
      padtext := bytes.Repeat([]byte{byte(padding)}, padding)
      return append(src, padtext...)
 }

Output is : "AAAAAAAAAAAAAAAAAAAAAEl8eI9S6j7mZTWG0vdwV1A="

I want to replicate the same in NodeJS.

     let iv = 'AAAAAAAAAAAAAAAA';
     let key = "dHRzbGNvbnNlbnR0ZWNobQ==";

     var cipher = crypto.createCipheriv('aes-256-cbc', keyBytes, iv);
     cipher.update(src, 'binary', 'base64');
     let y = cipher.final('base64');
     console.log("y --->> ",y);

But I'm getting error like

   crypto.js:194
   this._handle.initiv(cipher, toBuf(key), toBuf(iv));
           ^
   Error: Invalid key length

Can anyone please suggest me how to do this?

like image 555
sai Avatar asked Oct 27 '25 22:10

sai


1 Answers

The posted ciphertext can be reconstructed with the Go code if UTF-8 encoding is used for the key (and plaintext). The key is therefore 24 bytes in size, i.e. AES-192 is applied.

Note: (1) The key can also be Base64 decoded (AES-128), but this wouldn't produce the posted ciphertext. (2) Furthermore, the posted ciphertext doesn't correspond to the posted plaintext 1234565434, but to the plaintext 7989878678, as the decryption of the ciphertext reveals.

As mode, CFB is used. CFB is a stream cipher mode that doesn't require padding. The crypto module applies padding (PKCS7) by default, but automatically disables it for the stream cipher modes. Since the Go code (with the actually unnecessary padding) is the reference, padding must be forced in the NodeJS code. This is possible e.g. with the pkcs7-padding package.

Furthermore the Go code uses Base64url without padding, which is available e.g. with the base64url package.

The following NodeJS code produces a ciphertext that matches the posted ciphertext:

var crypto = require('crypto');
var pkcs7 = require('pkcs7-padding');
var base64url = require('base64url');

let iv = Buffer.from('00000000000000000000000000000000', 'hex');
let key = Buffer.from('dHRzbGNvbnNlbnR0ZWNobQ==','utf8');
let plaintext = Buffer.from('7989878678','utf8');
let plaintextPadded = pkcs7.pad(plaintext);

let cipher = crypto.createCipheriv('aes-192-cfb', key, iv);
let ivCiphertext = Buffer.concat([iv, cipher.update(plaintextPadded), cipher.final()]);
console.log("ivCiphertext  --->> ", base64url(ivCiphertext));

Note: As already mentioned in the comments, a key/IV pair may only be used once for security reasons, here.

like image 74
Topaco Avatar answered Oct 29 '25 15:10

Topaco



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!