1

我需要使用 DES-EDE3 算法和密钥加密字符串。php中的工作代码是这样的:

$encrypted = OpenSSL_encrypt($plain, "DES-EDE3", $key, OPENSSL_RAW_DATA);

但我想要它用于节点 js 项目。所以我像这样重写了这段代码:

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

但它给了我invalid key length错误。我尝试了其他方法,例如使用 md5 散列密钥,但在这种情况下,它不会给我与 php 代码相同的字符串。

4

1 回答 1

3

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.

于 2020-11-02T21:57:00.550 回答