简体   繁体   中英

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?

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, ie 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 eg with the pkcs7-padding package.

Furthermore the Go code uses Base64url without padding, which is available eg 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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM