使用加密在节点js中使用DES-EDE3加密

use DES-EDE3 encryption in node js using crypto

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

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

但我想要它用于 node 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 代码相同的字符串。

Base64 编码密钥 9GxTN6pRqOGNJTfDwG4Q6HGD5d2m6keR 对应于 Base64 解码为 24 字节密钥,因此是 Triple-DES 期望的密钥。 Triple-DES基于DES,对应DES的3次执行(encryption/decryption/encryption),每次执行使用其中一个key。

发布的PHP代码returns明文的结果如下敏捷的棕色狐狸跳过懒狗和发布的密钥:

$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

要显示数据,需要合适的编码,例如Base64。或者,可以省略 OPENSSL_RAW_DATA 标志而不是使用 base64_encode 的显式 Base64 编码(即可以使用 0),它隐式地进行 Base64 编码。

NodeJS 代码通过以下更改提供相同的结果:

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

请注意,let decodedData=... 行已被注释掉,因为它采用 UTF8 解码,因此 损坏 密文。

如果您想要原始数据,这将最接近缓冲区中的数据:

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

此处再次进行 Base64 编码以供输出。

des-ede3(等同于des-ede3-ecb)在ECB模式下表示Triple-DES。 Triple-DES 是一个过时的密码,应该替换为例如更高性能的 AES。另请注意,ECB 模式通常是不安全的。更好的选择是使用 GCM 模式的 CBC 或经过身份验证的加密。