Note a pit encountered when crypto's createCipheriv method was used to encrypt node.js

Node.js crypto module A set of encapsulations including hashing, HMAC, encryption, decryption, signature and verification of OpenSSL are provided. Specific methods of use can be referred to in the description of this article: node.js_crypto module.

This paper focuses on the pits encountered when using the createCipheriv method. The corresponding decryption algorithm createDecipheriv should be the same problem.

According to the description in the document, the createCipheriv method accepts three parameters: algorithm is used to specify encryption algorithms, such as aes-128-ecb, aes-128-cbc, key is used for encryption, and iv parameters are optional to specify the vector used for encryption. Note that the key must be 8/16/32 bits. If the encryption algorithm is 128, the corresponding key is 16 bits. If the encryption algorithm is 256, the corresponding key is 32 bits. The code is as follows:

const crypto = require("crypto");

function encrypt (key, iv, data) {
    let decipher = crypto.createCipheriv('aes-128-cbc', key, iv);
    // decipher.setAutoPadding(true);
    return decipher.update(data, 'binary', 'base64') + decipher.final('base64');
}

function decrypt (key, iv, crypted) {
     crypted = new Buffer(crypted, 'base64').toString('binary');
     let decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
     return decipher.update(crypted, 'binary', 'utf8') + decipher.final('utf8');
}

The following are the test results:

let key = '123456789abcdefg';
console.log('Encrypted key:', key);
let iv = 'abcdefg123456789';
console.log('Encrypted iv:', iv);
let data = "This is an example";
console.log("Data to be encrypted:", data);
let crypted = encrypt(key, iv, data);
console.log("After data encryption:", crypted);
let dec = decrypt(key, iv, crypted);
console.log("After data decryption:", dec);

The above encryption and decryption algorithms run well in node.js. But if the server is not using node. js, but a service written in Java, C # or C language, the result encrypted with node. JS can not be validated on the server. The reason may be that node. JS is different from other languages in the algorithm of createCipheriv, and this difference may also be reflected in the coding format. In the node.js code mentioned above, no matter how to modify the parameters of update() and final() methods in encrypt function, such as "utf8", "hex", or change the parameters into buffer s, although the encryption results will be different, the server-side validation will fail.

After many failed attempts, we can only identify crypto modules in node.js as different from implementations in other languages. So we have to choose other open source packages to replace crypto modules in node. js. After trying, aes-js Pack is a good choice. According to the description in the document, we modify the encrypt function in node.js as follows:

const aesjs = require('aes-js');

function encrypt (key, iv, data) {
    let aesCbc = new aesjs.ModeOfOperation.cbc(aesjs.utils.utf8.toBytes(key), aesjs.utils.utf8.toBytes(iv));
    let encryptedBytes = aesCbc.encrypt(aesjs.utils.utf8.toBytes(data));
    return aesjs.utils.hex.fromBytes(encryptedBytes);
}

function decrypt (key, iv, crypted) {
    let aesCbc = new aesjs.ModeOfOperation.cbc(aesjs.utils.utf8.toBytes(key), aesjs.utils.utf8.toBytes(iv));
    let encryptedBytes = aesCbc.decrypt(aesjs.utils.hex.toBytes(crypted));
    return aesjs.utils.utf8.fromBytes(encryptedBytes);
}

The above code requires 16 bits of data to be encrypted, and the test results are as follows:

let key = '123456789abcdefg';
console.log('Encrypted key:', key);
let iv = 'abcdefg123456789';
console.log('Encrypted iv:', iv);
let data = "Thisisanexample.";
console.log("Data to be encrypted:", data);
let crypted = encrypt(key, iv, data);
console.log("After data encryption:", crypted);
let dec = decrypt(key, iv, crypted);
console.log("After data decryption:", dec);

The encryption results calculated by aes-js can be verified by the server.

Tags: Javascript OpenSSL Java C

Posted on Thu, 10 Oct 2019 05:09:41 -0700 by uluru75