0

Delphi で LockBox 3 を使用して、Node.js の暗号ライブラリを使用して暗号化されたメッセージを解読しようとしています (そして失敗しています)。

node.js コード:

var crypto = require('crypto');
var cipher = crypto.createCipher('aes-256-ctr', 'my password');
var crypted = cipher.update('hello world', 'utf8', 'base64');
crypted += cipher.final(output_encoding);
console.log(crypted);

そこからの結果は

oyC1KRVx3JZBLlI=

Delphi コード:

var
  Codec: TCodec;
  CipherText: AnsiString;
begin
  Codec := TCodec.Create(nil);
  try
    Codec.CryptoLibrary := TCryptographicLibrary.Create(Codec);
    //
    Codec.StreamCipherId = 'native.StreamToBlock';
    Codec.BlockCipherId  = 'native.AES-256';
    Codec.ChainModeId    = 'native.CTR';
    //
    Codec.Password := 'my password';
    Codec.DecryptAnsiString(CipherText, 'oyC1KRVx3JZBLlI=');
    //
    Result := string(CipherText);
  finally
    Codec.Free;
  end;
end;

私は何が欠けていますか?

4

1 に答える 1

2

何が問題ですか?

問題は、両方のライブラリが異なるキーと初期化ベクトル (IV) を内部的に使用していることです。

AES 暗号はパスワードでは機能せず、キーと IV で機能することに注意してください。

暗号化ライブラリにパスワードを提供すると、内部メカニズムを使用してキーと IV が自動的に導出されます。

このメカニズムは明らかではありませんが、通常は暗号化ライブラリのドキュメントで説明されています。

cryptoモジュールのドキュメントにはnode.jsEVP_BytesToKeyOpenSSL の機能を使用してキーと IV を導出していると記載されています。

crypto.createCipher(algorithm, password) - 指定されたアルゴリズムとパスワードを使用する Cipher オブジェクトを作成して返します。

...

パスワードは、暗号鍵と初期化ベクトル (IV) を導出するために使用されます。値は、「バイナリ」でエンコードされた文字列または [Buffer[] のいずれかである必要があります。

crypto.createCipher() の実装は、OpenSSL 関数 EVP_BytesToKey を使用して、ダイジェスト アルゴリズムをMD5 に設定し、反復を 1 回行い、saltを使用せずに鍵を導出します。 同じパスワードが常に同じキーを作成するため、saltがないと辞書攻撃が可能になります。反復回数が少なく、暗号化されていない安全なハッシュ アルゴリズムにより、パスワードを非常に迅速にテストできます

Node.js v5.6.0 ドキュメントからの引用。

問題を解決するには?

適切な解決策は、暗号的に安全なハッシュ アルゴリズムを使用してパスワードからキーを取得し、そのキーと IV を手動で暗号化ライブラリに提供することです。

手っ取り早い汚い (そして非常に安全でない) 解決策は、同等の Delphi ルーチンを見つけて、EVP_BytesToKeyそれを使用して動作させることです。

同じパディング スキームを使用していることも確認してください。の暗号モジュールで使用されるものと互換性がある必要がありTCodecます。うまくいかない場合は、他のオプションも試してください。PaddingSchemepadPKCSnode.js


もう 1 つのオプションは、Delphi で OpenSSL を使用することです。これは、で使用されているものとすでに互換性があるはずnode.jsです。


また、あなたと同様の問題でこの質問を参照してください:

于 2016-02-13T11:40:46.650 に答える