1

PyCrypto ライブラリを使用して AES-CTR-256 データを復号化しようとしています。暗号文は、CryptoJS ライブラリに依存する Cryptocat マルチパーティ チャット Javascript コードによって生成されました。IV スキームは、Cryptocat Multiparty Protocol Specificationで説明されているとおりです。

初期化ベクトル (IV) は 16 バイトで構成されます。12 バイトはランダムに生成され、4 バイトはカウンターとして機能し、ブロックごとに 1 回インクリメントされます。

(12 のランダム バイトは、4 つのカウンター バイトの前に来ます。)

ここに私のPythonコードがあります:

import struct
import base64
import Crypto.Cipher.AES

def bytestring_to_int(s):
    r = 0
    for b in s:
        r = r * 256 + ord(b)
    return r

class IVCounter(object):
    def __init__(self, prefix="", iv="\x00\x00\x00\x00"):
        self.prefix = prefix
        self.initial_value = iv

    def increment(self, b):
        if b == "\xff\xff\xff\xff":
            raise ValueError("Reached the counter limit")
        return struct.pack(">I", bytestring_to_int(b)+1)

    def __call__(self):
        self.initial_value = self.increment(self.initial_value)
        n = base64.b64decode(self.prefix) + self.initial_value
        return n

def decrypt_msg(key, msg, iv):
    k = base64.b16decode(key.upper())
    ctr = IVCounter(prefix=iv)
    aes = Crypto.Cipher.AES.new(k, Crypto.Cipher.AES.MODE_CTR, counter=ctr)
    plaintext = aes.decrypt(msg)
    return plaintext

if __name__ == "__main__":
    key = 'b1df40bc2e4a1d4e31c50574735e1c909aa3c8fda58eca09bf2681ce4d117e11'
    msg = 'LwFUZbKzuarvPR6pmXM2AiYVD2iL0/Ww2gs/9OpcMy+MWasvvzA2UEmRM8dq4loB\ndfPaYOe65JqGQMWoLOTWo1TreBd9vmPUZt72nFs='
    iv = 'gpG388l8rT02vBH4'
    plaintext = decrypt_msg(key, msg, iv)
    print plaintext

そして、これは Javascript で同じことを行う方法です:

  1. CryptoCat 拡張機能をインストールする
  2. CryptoCat を実行する
  3. 開発者コンソールを起動します (Chrome/Firefox では F12)。
  4. これらのコード行を実行します

key = 'b1df40bc2e4a1d4e31c50574735e1c909aa3c8fda58eca09bf2681ce4d117e11';
msg = 'LwFUZbKzuarvPR6pmXM2AiYVD2iL0/Ww2gs/9OpcMy+MWasvvzA2UEmRM8dq4loB\ndfPaYOe65JqGQMWoLOTWo1TreBd9vmPUZt72nFs=';
iv = 'gpG388l8rT02vBH4';
opts = {mode: CryptoJS.mode.CTR, iv: CryptoJS.enc.Base64.parse(iv), padding: CryptoJS.pad.NoPadding};
CryptoJS.AES.decrypt(msg, CryptoJS.enc.Hex.parse(key), opts).toString(CryptoJS.enc.Utf8);

期待される出力: "Hello, world!ImiAq7aVLlmZDM9RfhDQgPp0CrAyZE0lyzJ6HDq4VoUmIiKUg7i2xpTSPs28USU8". 予想通り、これは Javascript で動作します。

ただし、Python コードの出力は意味不明です。repr(平文) は以下を与えます:

'\x91I\xbd\n\xd5\x11\x0fkE\xaa\x04\x81V\xc9\x16;.\xe3\xd3#\x92\x85\xd2\x99\xaf;\xc5\xafI\xac\xb6\xbdT\xf4{l\x17\xa1`\x85\x13\xf2\x8e\x844\xac1OS\xad\x9eZ<\xea\xbb6\x9dS\xd5\xbc\xfd\xc4\r\xf94Y~\xaf\xf3\xe0I\xad\xa6.\xfa\x7f\xf8U\x16\x0e\x85\x82\x8c\x8e\x04\xcb,X\x8b\xf7\xef\xb2\xc2\xe3~\xf1\x80\x08L\x8b \x9f\xaf\x0e\x0b'

なぜこれが起こっているのかわかりません。私の IVCounter 実装は、JS コードが使用するスキームと一致していると確信しています。CryptoJS の NoPadding オプションに相当する Python がないということでしょうか? 私は困惑しています。

助けてくれてありがとう!

4

3 に答える 3

0

他の誰かの AES デクリプタで AES 暗号化されたメッセージを解読できないのはなぜですか?

Python 復号化の使用方法は、その質問に対する回答に従って変更する必要があります。

于 2013-04-05T15:19:38.973 に答える
0

カウンターをインクリメントする方法に問題があります。どうやら、正しいカウンター値が間違った場所に適用されているようです。これは、この問題に対処するフォローアップの質問です。Python と Javascript を使用した AES CTR モードの奇妙な問題

于 2013-04-17T00:20:51.553 に答える