2016-06-30 31 views
0

私はnode.jsのcryptモジュールを使用して、標準ではないライブラリでopensslライブラリを使用した別のプログラムで暗号化されたファイルを解読しようとしています。非標準的なことは、ラウンドの数と塩の場所がopensslが使うデフォルトと異なることを意味します。結果的に私は最初に塩を抽出してから、その実際の解読を行う前に結果の記述にReadStreamを作成しています。パイプ経由でnode.jsでAES256を解読する

私は2つのルーチンを持っています。最初のものはdecrypt.updatedecrypt.finalを使用して解読を実行します。私はこの方法でファイルを解読することができます。 2番目はpipeを使用して復号化を実行します。私はそれを使用しようとすると、私はこのエラーを取得:

私は自分のコードを実行しようとすると、私が手にエラーがある:

digital envelope routines:EVP_DecryptFinal_ex:wrong final block length

作業や失敗した機能以下の通りです。参照される "binary_concat"関数は、バイナリ文字列の場合にはa+bに相当します。a+bが正しく動作しないことが判明する前に、数時間のデバッグが必要でした。

function do_decrypt_works(infile,password,salt) { 
    var outfile = fs.createWriteStream("/tmp/test.out") 
    var text = fs.readFileSync(infile_filename).slice(8) // hack since we aren't using infile in this case 
    var rounds = 28 
    data00 = binary_concat(password,salt,"") 

    var hash1 = do_rounds(data00) 
    var hash1a = binary_concat(hash1,password,salt) 
    var hash2 = do_rounds(hash1a,password,salt) 
    var hash2a = binary_concat(hash2,password,salt) 
    var hash3 = do_rounds(hash2a,password,salt) 

    var key = binary_concat(hash1,hash2,"") 
    var iv = hash3 

    var decrypt = crypto.createDecipheriv('aes-256-cbc', key, iv) 

    var content = decrypt.update(text, "binary", "binary"); 
    content += decrypt.final("binary"); 
} 

function do_decrypt_fails(infile,password,salt) { 
    var outfile = fs.createWriteStream("/tmp/test.out") 
    var rounds = 28 
    data00 = binary_concat(password,salt,"") 

    var hash1 = do_rounds(data00) 
    var hash1a = binary_concat(hash1,password,salt) 
    var hash2 = do_rounds(hash1a,password,salt) 
    var hash2a = binary_concat(hash2,password,salt) 
    var hash3 = do_rounds(hash2a,password,salt) 

    var key = binary_concat(hash1,hash2,"") 
    var iv = hash3 

    var decrypt = crypto.createDecipheriv('aes-256-cbc', key, iv) 
    infile.pipe(decrypt).pipe(outfile) 
} 
documentationによれば

、両方createDecipherおよび上記の技術のいずれかと共に使用することができるクラスDecipherのインスタンスを返すcreateDecipheriv

出典:

First

Second

Third

答えて

0

はい、あなたは(i = 1; i < rounds; i++)をループするが、その後とにかく最初の3回のダイジェストを取っている(結果の最初の48バイト、終了48バイトをはるかに超え、ループを18回通過するとループが繰り返し連結されます)。

とにかく、アルゴリズムを読んで、間違った場所でループしています。最初の関数がうまくいくように見えますが、ハッシュに繰り返し回数を追加する必要があります。

function md5(data, count) { 
    var hash = crypto.createHash('md5'); 
    hash.update(data); 
    for i = 0; i < count; i++ // PSEUDO-CODE !!! 
     hash.update(hash)  // PSEUDO-CODE re-hash the hash 
    return new Buffer(hash.digest('hex'), 'hex'); 
} 
+0

私は全体ラウンドで少し混乱しています。余分なラウンドが連結されて使用されないと、より多くのラウンドがより安全になるのはなぜですか?とにかく、他のいくつかの問題も発見されました...最近のところ、hash.digestは16バイトの値を作成するだけですが、32バイトの長さにする必要があります。最初の16はまさに私が期待しているものと一致するので、エンコードの問題ではないと思います。 (EVP_BytesToKeyの出力と比較して、余分な16バイトが得られますか?) – Michael

+0

KEY/IV計算には間違いがあります。EVP_BytesToKeyの出力との比較は最初のラウンドのみです! – Michael

+0

ああ待って、私は見ると思う...あなたは "ハッシュ*ラウンド*回数"を3回、1回ではないのですか? – Michael

関連する問題