我需要在Nodejs中复制http://tripledes.online-domain-tools.com/中3DS CBC加密的结果。
这是我的代码:
const crypto = require('crypto');
const cipher = crypto.createCipher('des-ede3-cbc', key);
password = Buffer.from('MYPASS', 'utf8');
let encrypted = [cipher.update(password)];
encrypted.push(cipher.final());
encrypted = Buffer.concat(encryptedArr);
console.log(encrypted.toString('hex'));
tripledes.online-domain-tools.com的结果是:
请注意,结果应该是59 30 20 02 a5 8c dd 5e,但是我的代码给了我33 97 d8 b0 e3 00 d1 53。
我缺少什么?
EDIT2: 根据您的建议,我更改了我的代码(还添加了一些使用NIST出版物指南进行的测试):
const crypto = require('crypto');
function encrypt (inputkey, keyformat, password, passwordformat) {
let shortkey = Buffer.from(inputkey, keyformat);
let key = Buffer.alloc(24);
key.fill('\0');
for (i = 0; i < shortkey.length; i++) {
key[i] = shortkey[i];
}
let IV = Buffer.alloc(8);
const cipher = crypto.createCipheriv('des-ede3-cbc', key, IV);
password = Buffer.from(password, passwordformat);
let encryptedArr = [cipher.update(password)];
encryptedArr.push(cipher.final());
encrypted = Buffer.concat(encryptedArr);
return encrypted;
}
console.log(encrypt('1046913489980131','hex','0000000000000000','hex')); // works
console.log(encrypt('1007103489988020','hex','0000000000000000','hex')); // works
console.log(encrypt('10071034C8980120','hex','0000000000000000','hex')); // works
console.log(encrypt('1046103489988020','hex','0000000000000000','hex')); // works
console.log(encrypt('MYKEY','utf8','MYPASS','utf8')); // fails
NIST的每个Permutation Operation Known Answer Test
效果都很好,但其他一些例子(包括其中一个图片)都失败了
我正在使用这个阴暗页面进行测试的原因是因为我的服务提供商正在使用它作为参考。
答案 0 :(得分:2)
这个网站在一段时间内给我带来了一些麻烦,这里是它在内部使用的实现,将密钥扩展为24字节! 我将谈论三元组,但我想这将适用于本网站使用的其他算法
第1步
它首先检查输入的密钥是否具有预期的长度,(您可以在该网站的底部找到一个表,告诉每个加密算法的密钥长度)
如果没有,它将以0x00
字节完成,如下所示:
var key;// is a string containing the bytes wich will be used to encrypt the msg
var nullByte = 0x00;
var padding_needed;
for (var i=key.length ;i < expected_key_length ; ++)
{padding_needed =padding_needed + nullBute.tostring(16); }
key = key + padding_needed
所以例如它对3DES的期望长度是24个字节;如果你恰好输入这样的15个字节(112233445566778899aabbccddeeff),那就像你输入的那样(112233445566778899aabbccddeeff00)
<强>步骤2 强>
在三元组的情况下,算法将16字节扩展到24字节密钥(这是算法所需的密钥长度)这个网站有一个简单的方法来做到这一点 它复制前8个字节并将其附加到密钥的末尾,如此
key =key + key.substring(0,8);
这是将要使用3DES加密函数
的关键openssl不使用这个简单的方法,例如,open ssl使用密钥的MD5的前8个字节,并将它们附加到原始密钥的16个字节,以获得3DES所需的24字节密钥,像这样
key = key + (MD5(key)).substring(0,8);
<强>摘要强>
如果您输入密钥112233445566778899AABBCCDDEEFF
,则该工具中的与输入112233445566778899AABBCCDDEEFF00
的情况相同,就像您输入112233445566778899AABBCCDDEEFF001122334455667788
一样,为了解决您的问题,您应该为您的功能提供完成你给该网站的24个字节的密钥,你肯定会得到相同的结果,因为nodejs可能与openssl做同样的事情来扩展密钥(使用md5)
<强> PS 强> 如果您正在使用cbc模式,那么尝试将IV指定为8字节的\ x00,如此“0000000000000000” 结果会一样!!
这是您的代码的工作实现,您可以在网站上查看它
const crypto = require('crypto');
function encrypt (inputkey, keyformat, password, passwordformat) {
let shortkey = Buffer.from(inputkey, keyformat);
let key = Buffer.alloc(24);
key.fill('\0');
for (i = 0; i < shortkey.length; i++) {
key[i] = shortkey[i];
}
let IV = Buffer.alloc(8);
var expansionStart = shortkey.length>16?shortkey.length:16;
for (i=expansionStart;i<24;i++){
key[i]=key[i-expansionStart];
}
console.log(key);
const cipher = crypto.createCipheriv('des-ede3-cbc', key, IV);
password = Buffer.from(password, passwordformat);
let encryptedArr = [cipher.update(password)];
encryptedArr.push(cipher.final());
encrypted = Buffer.concat(encryptedArr);
return encrypted;
}
var enc = encrypt("112233445566778899AABBCCDDEEFF","hex","password","utf8");
console.log(enc);