2017-09-21 19 views
1

私はNodejsで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の結果である:結果は59 30 20 02 A5であることが

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

注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は素晴らしいが、他のいくつかの作品例(画像の1つを含む)が失敗するだけです

私のサービスプロバイダが参照として使用しているため、この日陰のページでテストしている理由があります。

+1

でそれを確認することができ、あなたのコードの作業を実装したものです。 –

+1

私の野生の推測..ウェブページには、キーが必要なキーの長さに合わせて延長され、キーのsha1の一部がIVとして使用されることが記載されています。あなたのコードはそれをしません – gusto2

+0

私はそれを見落としました、私はそれを確認するつもりです –

答えて

1

このサイトはいくつかの問題を抱えていましたが、ここでは内部的にキーを24バイトに拡張する実装があります。 、私はトリプルDESについて話をするつもりですが、私は入力されたキーは、それがあることを期待している長さを持っている場合、これは、このサイトで使用される他のアルゴリズム

ステップ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バイトです。あなたはこのようなわずか15バイト(112233445566778899aabbccddeeff)を入力するために起こる場合は、トリプルDESの場合は24バイトのキーに16のバイトを拡張するためのアルゴリズムで(112233445566778899aabbccddeeff00)

STEP2

を入力した場合、それは次のようになりますこのサイトは それコピー最初の8つのバイトは、この

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

ようなキーの末尾に追加することを行うための簡単なアプローチを持っている(アルゴリズムによって必要とされるキーの長さである)、それはキーでありますそれは与えられるつもりです例えば、OpenSSLはキーのMD5の最初の8バイトを使用して元のキーの16バイトに追加します。そのツールでこの

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

概要

のような3DESによって要求された24バイトのキーは、キー112233445566778899AABBCCDDEEFFを入力する場合は、112233445566778899AABBCCDDEEFF00と同じに入ったかのようにあなたが112233445566778899AABBCCDDEEFF001122334455667788を入力した場合と同じですあなたのプロを解決するためにあなたは、あなたがそのサイトに与えたキーの完全な24バイトを与えるべきであり、あなたは確かに同じ結果を得るでしょう、nodejsはおそらくopensslがキーを展開するのと同じことをしています(md5を使用します)

PS あなたのケースであるcbcモードを使用している場合、この "0000000000000000"のように\ x00の8バイトを指定してください。 結果は同じになります!ここ

は、初期化ベクトルが有罪であるかもしれないサイト

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);