2017-09-21 17 views
1

NodeS에서 3DS CBC 암호화 결과를 http://tripledes.online-domain-tools.com/에 복제해야합니다.TripleDes CBC Nodejs 구현 문제

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의 결과이다 :

내 코드는 결과가 있어야

Note that the result should be 59 30 20 02 a5 8c dd 5e, but my code gives me 33 97 d8 b0 e3 00 d1 53

하는 것으로 59 30 20 02 A5 8c dd 5e,하지만 내 코드 33 97 d8 b0 e3 00 d1 53.

내가 무엇이 누락 되었습니까?

Edit2가 :

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하지만, 다른 몇 가지 : 당신의 제안에 따라 , 내 코드는 (또한 NIST 간행물의 안내로 만든 몇 가지 테스트를 추가) 변경 예제 (이미지 중 하나 포함)가 실패합니다.

내 서비스 공급자가 참조로 사용하고 있기 때문에이 그늘진 페이지로 테스트하는 이유가 있습니다.

+1

초기화 벡터 유죄 수 있습니다에서 확인할 수있다. –

+1

웹 페이지에는 필요한 키 길이와 일치하도록 키가 길어지고 키의 sha1을 IV로 사용한다고 나와 있습니다. 귀하의 코드는 그렇게하지 않습니다 – gusto2

+0

나는 그것을 간과 할 것입니다. –

답변

1

이 사이트는 몇 시간 동안 약간의 문제를 일으켰습니다. 여기에 24 바이트가되도록 키를 확장하기 위해 내부적으로 사용하는 구현이 있습니다. 내가 TRIPLEDES에 대해 이야기 할 것입니다하지만 난이이 사이트

단계에서 사용되는 다른 알고리즘에 적용되는 것 같아요 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 용 pect는 24 바이트입니다. 이 (112233445566778899aabbccddeeff)과 같은 15 바이트를 입력 할 일이 있다면 그것은 당신이 TRIPLEDES의 경우 24 바이트 키에 16 바이트를 확장 알고리즘을 (112233445566778899aabbccddeeff00)

2 단계

를 입력 한 경우처럼 될 것입니다 이 사이트 그것을 복사 처음 8 바이트이

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

같은 키의 말미에 추가하는 것을 수행하는 간단한 방법이있다 (알고리즘에 의해 요구되는 키 길이 임) 및 그 열쇠 그것은 주어질 것입니다. 예를 들어 openssl에서이 간단한 접근법을 사용하지 않는 경우 open ssl은 키 MD5의 처음 8 바이트를 사용하고 원래 키의 16 바이트에 추가합니다. 당신이 112233445566778899AABBCCDDEEFF001122334455667788를 입력 한 것처럼 당신이 112233445566778899AABBCCDDEEFF00을 입력하고 같은 것처럼 키 112233445566778899AABBCCDDEEFF을 입력하면 해당 도구에서이

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

요약

같은 3DES에 의해 요구되는 24 바이트 키는 동일합니다 그래서 당신의 프로를 해결하기 위해 blem 당신은 그 사이트에 준 완전한 24 바이트의 키를 제공해야하고, 똑같은 결과를 얻을 것입니다. nodejs는 아마도 openssl이 키를 확장하는 것과 같은 일을합니다 (md5 사용)

PS 당신의 케이스 인 cbc 모드를 사용하는 경우 IV가 \ x00의 8 바이트가되도록 지정하십시오. "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);