1

Rijndael を使用して、DCPcrypt で暗号化されたデータの復号化に取り組んでいます。Python を使用して復号化したかったのですが、問題が発生しています。私は特に暗号に精通しているわけではありません(大学のコースを受講しましたが、それだけです)。また、Delphi プログラマーでもありません。そのため、DCPcrypt が正確に何をしているのかを解読する努力を妨げている可能性があります。

これは、Delphi コードの要点です。

Cipher: TDCP_rijndael;
begin
Cipher:= TDCP_rijndael.Create(nil);
Cipher.InitStr(PasswordField.Text);
Cipher.EncryptCBC(encryptString[1],encryptString[1],Length(encryptString));

そのため、実装では (パスワード フィールドから取得した) キーを使用しますが、IV は使用しません。一方、PyCrypto には IV が必要です。DCPcrypt コードの内部を検索すると、IV がゼロの場合、ECB 暗号化を使用して 0xff の文字列から IV が読み込まれるようです。

procedure TDCP_rijndael.Init(var Key; Size: longint; IVector: pointer);
....
  if IVector= nil then
  begin
    FillChar(IV,Sizeof(IV),$FF);
    {$IFDEF CFORM}Encrypt(IV,IV){$ELSE}RijndaelEncryptECB(Data,IV,IV){$ENDIF};
    Move(IV,LB,Sizeof(LB));
  end

スタティック IV を使用しているようです。しかし、私はこれを機能させることができません。これが私の PyCrypto での実装です。私が間違っていることはありますか?

key = "password"
s = hashlib.sha1()
s.update(key)
key = s.digest()
key = key[:16]

# Set up the IV, note that in ECB the third parameter to the AES.new function is ignored since ECB doesn't use an IV
ecb = AES.new(key, AES.MODE_ECB, '\xff' * 16)
iv = ecb.encrypt('\xff' * 16)

cipher = AES.new(key, AES.MODE_CFB, iv)
msg = cipher.decrypt(ct[:16])

Delphi コードを使用して暗号化され、base64 でエンコードされたプレーン テキストがいくつかあります。使用されたキーは、上記でハードコーディングされた文字列のパスワードでした。私の実装を使用して、文字化けしたバイトの束を復号化します。

k8b+uce5Fkp7Hbk/CaGYcuEWTfxlI05as88lJL0mHmJxLsKWqki2YwiFPU9Rx8qiUC2cvWZrQIONkw==

どんな助けでも大歓迎です。

4

2 に答える 2

0

提案や考えのランダムな品揃え:

  1. 静的IVは、既知の平文攻撃への扉を開くため、一般的にセキュリティリスクです。
  2. dcpcryptソースを見ると、IVを指定する方法があるようです。エラーの原因として誤ったIVを排除する以外の理由がない場合、そうしない理由はありますか?
  3. 同様に、CBCの代わりにECBを試して、IVを完全に排除し、問題がIVにあるのか、他の場所(キー、データ、または構成)にあるのかを特定できます。
于 2012-09-12T05:13:48.327 に答える
0

免責事項:私はPythonに非常に

慣れていませんが、これを 試してください:変更してみてください

key = key[:16]

key = key + bytes([0,0,0,0])

これにより、24バイトのキーが得られますが、これでうまくいくはずです。

DCP では任意の長さのキーが許可されますが、Crypto では 16、24、または 32 バイトのキーが要求されます。デフォルトでは、DCP は SHA1 を使用してキーを生成します。キーの長さは 20 バイトです。この DCP に基づいて、keylength <= 24 のロジックを使用し、key[:16] が持つ効果である keylength <= 16 のロジックではなく、キーをゼロでパディングします。

また、これが単なるタイプミスかどうかはわかりませんが、AES モードを変更してみてください。

cipher = AES.new(key, AES.MODE_CFB, iv)

cipher = AES.new(key, AES.MODE_CBC, iv)

これにより、入力が復号化されます。ただし、DCP はパディングを行わないため (私が思うに)、元のソース テキストのパディングを検討する必要がありますが、Crypto では復号化に 16 の倍数が必要です。

于 2012-09-13T14:13:59.763 に答える