TripleDes CBC Nodejs实现问题

我需要在NodeJs中复制http://tripledes.online-domain-tools.com/中的3DS CBCencryption结果。

这是我的代码:

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

注意结果应该是59 30 20 02 a5 8c dd 5e,但是我的代码给了我33 97 d8 b0 e3 00 d1 53。

我错过了什么?

编辑2:按照你的build议,我改变了我的代码(还添加了一些与NIST出版物的指导进行的testing):

 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 

每个Permutation Operation Known Answer Test NIST的Permutation Operation Known Answer Test工作很好,但其他几个例子(包括图像的一个)只是失败

我正在testing这个黑幕的原因是因为我的服务提供商正在使用它作为参考。

这个网站在一段时间内让我有些麻烦,好了,这里是它内部使用的实现来扩展一个24字节的密钥! 我要谈谈tripleind,但我想这将适用于本网站使用的其他algorithm

步骤1

它首先检查input的密钥是否具有它期望的长度(如果没有,则可以在该站点的底部find一个表,告诉每个encryptionalgorithm的密钥长度),如果它不会以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字节; 如果你碰巧input了这样的15个字节(112233445566778899aabbccddeeff),那就好像你input了(112233445566778899aabbccddeeff00)

第2步

在三联体的情况下,将16个字节扩展为24个字节的密钥(这是algorithm所需的密钥长度)的algorithm,这个站点有一个简单的方法来做,它复制前8个字节,并将其附加到这样的关键

 key =key + key.substring(0,8); 

这是3DESencryptionfunction将要使用的关键

openssl并不使用这个简单的方法,例如,open ssl使用密钥MD5的前8个字节,并将它们附加到原始密钥的16个字节,以获得3DES所需的24个字节的密钥,像这样

 key = key + (MD5(key)).substring(0,8); 

概要

在这个工具,如果你input密钥112233445566778899AABBCCDDEEFF是一样的,如果你input112233445566778899AABBCCDDEEFF00相同,如果你input112233445566778899AABBCCDDEEFF001122334455667788如此解决你的问题,你应该给你的function,你给该网站的密钥的完整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);