いくつかの背景情報、実際の質問のためにこの部分をスキップすることができます
これは、stackoverflowでのこのトピックに関する私の3番目の質問です。完全を期すために、これらはcrypt-jsとPyCryptoを使用したAESと、pythonおよびjavascriptでのAES de/encryptionとの一致に関する他の質問です。残念ながら、私の最後の試みでは、元の質問に対して2つの反対票がありました。問題は、私の本当の質問が何であるかを私でさえ知らなかったということでした。探していた本当の質問を見つけるために掘り下げました。コメントのフィードバックといくつかの追加情報を読んで、質問を更新しました。私は正しい質問を発掘していると思います。しかし、私の問題は、私の更新後にそれ以上のビューを取得しませんでした。ですから、この質問がより明確で理解しやすくなることを心から願っています-私の問題が今何であるかを知っていても:D
このクールなコミュニティにstackoverflowを作成していただき、ありがとうございます。ここで問題の解決策を見つけることがよくあります。悪い質問にはフィードバックを送り続けてください。そうすれば、それらを改善および更新して、この膨大な知識とソリューションのデータベースを増やすことができます。そして、私の英語の文法とスペルを自由に修正してください。
問題
JavascriptのAES
このJavascriptによるAES256CTRモードの実装で復号化できる暗号化された文字列があります
password = "myPassphrase"
ciphertext = "bQJdJ1F2Y0+uILADqEv+/SCDV1jAb7jwUBWk"
origtext = Aes.Ctr.decrypt(ciphertext, password, 256);
alert(origtext)
これにより、文字列が復号化され、アラートボックスがThis is a test Text
ポップアップ表示されます。
PyCryptoを使用したAES
今、私はこの文字列をpythonとPyCryptoで復号化したい
password = 'myPassphrase'
ciphertext = "bQJdJ1F2Y0+uILADqEv+/SCDV1jAb7jwUBWk"
ctr = Counter.new(nbits=128)
encryptor = AES.new(key, AES.MODE_CTR, counter=ctr)
origtext = encryptor.decrypt(base64.b64decode(ciphertext))
print origtext
このコードは実行されません。取得しValueError: AES key must be either 16, 24, or 32 bytes long
ます。PyCryptoでさらに多くのことを実行し、次に復号化メソッドを呼び出す必要があることを認識したとき、私は自分が何をしなければならないかを理解するために調査を開始しました。
調査
私が最初に理解した基本的なことは次のとおりです。
- AES 256ビット(?)。ただし、AES標準は128ビットです。パスフレーズを32バイトに増やすだけで十分ですか?
- カウンターモード。AES.MODE_CTRを使用してPyCryptoに簡単に設定できます。ただし、counter()メソッドを指定する必要があります。そこで、PyCryptoが提供する基本的なバイナリカウンターを使用しました。これはJavascriptの実装と互換性がありますか?彼らが何をしているのか理解できません。
- 文字列はbase64でエンコードされています。大きな問題ではありません。
- 一般的なパディング。パスフレーズと暗号化された文字列の両方。
パスフレーズの場合、彼らはこれを行います:
for (var i=0; i<nBytes; i++) {
pwBytes[i] = isNaN(password.charCodeAt(i)) ? 0 : password.charCodeAt(i);
}
それから私はPythonでこれをしました
l = 32
key = key + (chr(0)*(l-len(key)%l))
しかし、これは役に立ちませんでした。私はまだ?
A???B??d9= ,?h????'
次のコードで奇妙な文字列を取得します
l = 32
key = 'myPassphrase'
key = key + (chr(0)*(l-len(key)%l))
ciphertext = "bQJdJ1F2Y0+uILADqEv+/SCDV1jAb7jwUBWk"
ctr = Counter.new(nbits=128)
encryptor = AES.new(key, AES.MODE_CTR, counter=ctr)
origtext = encryptor.decrypt(base64.b64decode(ciphertext))
print origtext
それから私はJavascriptの実装についてもっと読みましたそしてそれは言います
[...]この実装では、最初のブロックは最初の8バイトにナンスを保持し、次の8バイトにブロックカウントを保持します。[...]
これが解決策の鍵になると思います。そこで、Javascriptで空の文字列を暗号化するとどうなるかをテストしました。
origtext = ""
var ciphertext =Aes.Ctr.encrypt(origtext, password, 256);
alert(ciphertext)
警告ボックスに/gEKb+N3Y08=
(12文字)が表示されます。しかし、なぜ12?8 + 8 = 16バイトではないでしょうか?とにかく、andまたはで復号化をテストすることにより、Python復号化でブルートフォース方式を試しました。これは非常に恥ずかしい試みであることを私は知っていますが、私はますます必死になりました。そしてそれもうまくいきませんでした。for i in xrange(0,20):
ciphertext[i:]
base64.b64decode(ciphertext)[i:]
将来の見通しも同じ方法で暗号化を実装することです。
追加情報
暗号化された文字列は、もともとこのJavascript実装で暗号化されていませんでした。これは、別のソースからのものです。私は、Javascriptコードが正しいことをすることを認識しました。したがって、この種の実装は「標準」のようなものであると私は断言します。
質問
PyCryptoを使用した文字列からの暗号化と復号化がJavascript実装の場合と同じであるため、JavascriptとPythonの間でデータを交換できるようにするには、どうすればよいですか?また、別の暗号ライブラリを提案できる場合は、Pythonで別の暗号ライブラリに切り替えます。さらに、私はあらゆる種類のヒントやフィードバックに満足しています。
そして、すべては、暗号化された文字列にナンスとブロックカウントを含めるにはどうすればよいかということになります。復号化のためにこの情報を抽出するにはどうすればよいですか?