I need to encrypt a string using DES-EDE3 algorithm and a key. The working code for that in php is like this:
$encrypted = OpenSSL_encrypt($plain, "DES-EDE3", $key, OPENSSL_RAW_DATA);
but I want it for node js project. So I rewrote this code like so:
let cipher = crypto.createCipheriv("des-ede3", "the key", null);
let encryptedData = cipher.update("the data", "utf8", "base64") + cipher.final("base64");
let decodedData= Buffer.from(encryptedData , "base64").toString(); //cause i want it raw
But it gives me the invalid key length
error. I tried other ways like hashing the key using md5 but in that case it does not give me the same string that the php code does.
The Base64 encoded key 9GxTN6pRqOGNJTfDwG4Q6HGD5d2m6keR
corresponds Base64 decoded to a 24 bytes key and thus a key that Triple-DES expects. Triple-DES is based on DES and corresponds to three executions of DES (encryption/decryption/encryption), using one of the keys for each execution.
The posted PHP code returns the following result for the plaintext The quick brown fox jumps over the lazy dog and the posted key:
$encrypted = openssl_encrypt('The quick brown fox jumps over the lazy dog', 'des-ede3', base64_decode('9GxTN6pRqOGNJTfDwG4Q6HGD5d2m6keR'), OPENSSL_RAW_DATA);
print(base64_encode($encrypted)); // +sEO1gYe1Jk1+cslkLHDlSPwEOeFUBqKS7giqBnishiAcC9YfPxYiIJssg2Xu+e6
To display the data a suitable encoding is required, e.g. Base64. Alternatively instead of the explicit Base64 encoding with base64_encode
the OPENSSL_RAW_DATA
flag could be omitted (i.e. 0
could be used), which implicitly Base64 encodes.
The NodeJS code provides the same result with the following changes:
var crypto = require('crypto');
let cipher = crypto.createCipheriv("des-ede3", Buffer.from('9GxTN6pRqOGNJTfDwG4Q6HGD5d2m6keR','base64'), null);
let encryptedData = cipher.update("The quick brown fox jumps over the lazy dog", "utf8", "base64") + cipher.final("base64");
//let decodedData= Buffer.from(encryptedData , "base64").toString(); //cause i want it raw
console.log(encryptedData); // +sEO1gYe1Jk1+cslkLHDlSPwEOeFUBqKS7giqBnishiAcC9YfPxYiIJssg2Xu+e6
Note that the line let decodedData=...
has been commented out, because it UTF8-decodes and thus corrupts the ciphertext.
If you want to have raw data, this would be closest to data in a buffer:
let encryptedData = Buffer.concat([cipher.update("The quick brown fox jumps over the lazy dog", "utf8"), cipher.final()]);
console.log(encryptedData.toString('base64')); // +sEO1gYe1Jk1+cslkLHDlSPwEOeFUBqKS7giqBnishiAcC9YfPxYiIJssg2Xu+e6
which again are Base64 encoded here for output.
des-ede3
(equivalent to des-ede3-ecb
) denotes Triple-DES in ECB mode. Triple-DES is an outdated cipher that should be replaced by e.g. the higher performant AES. Also note, that the ECB mode is generally insecure. Better choices are CBC or authenticated encryption using GCM mode.