先週末、暗号文が次の 16 進数である暗号チャレンジがありました。
FC 89 BF C2 B0 5F 1C 2E 64 B8 78 43 92 78 3A C9
これは AES/Rijndael 128 ビット ECB を使用して暗号化されており、キーは REDRYDER であることは確かです。また、これを確認するためのソリューションがすでに投稿されています。プレーン テキストは FLAG=DAISY です。ソルトや IV 文字列なしでこれを復号化する簡単な PHP mcrypt スクリプトを作成し、適切に復号化しました。ただし、openssl を使用しようとすると、プレーン テキストを取得できません。
echo "0: FC 89 BF C2 B0 5F 1C 2E 64 B8 78 43 92 78 3A C9" | xxd -r | openssl aes-128-ecb -d -k REDRYDER -nosalt -nopad ; echo
これは単にバイナリ データを出力するだけです。また、入力を dd conv=swab に渡してバイト スワップを行うことも試みました。
何が間違っているのでしょうか?
答え1
コマンドopenssl
ライン ツールは OpenSSL ライブラリのデモです。インターフェイスがかなり雑然としていて、ドキュメントも貧弱です。OpenSSL ライブラリのテスト以外の用途には使用しないことをお勧めします。(はい、 で CA を管理している人もいますopenssl
。彼らの正気を心配しています。)
エーエスパスワードではなくキーで動作します。AES-128 キーは 16 バイトです。
このオプションは-k
入力としてキーではなくパスワードを受け取ります。このパスワードはハッシュ化されてキーを導出します。デフォルトは MD5 ですが、コマンドライン オプション で上書きできます-md
。私が見る限り、これはマニュアルには記載されていないので、ソース ( apps/enc.c
、 の呼び出しEVP_BytesToKey
) を読む必要があります。MD5 ダイジェストは任意の文字列から 16 バイトの値を生成しますが、ここで使用されているのはこれではありません。この場合、キーは実際には で、REDRYDER\0\0\0\0\0\0\0\0
は\0
null バイトです。
オプションを使用-K
すると、16 進数のキーを渡すことができます。キー サイズよりも少ないバイト数を渡した場合、OpenSSL は null バイトで完了します。したがって、キー を渡すにはREDRYDER\0\0\0\0\0\0\0\0
、 を渡すことができます。$(echo REDRYDER | od -An -tx1 | tr -d ' ')
これは です。5245445259444552
暗号文ブロック FC89BFC2B05F1C2E64B8784392783AC9 をキー 524544525944455200000000000000000 を使用して AES-128-ECB 復号化操作を行うと、464c41473d44414953590000000000000 (バイト シーケンスを表すために 16 進数を使用) が生成されます。つまり、 ですFLAG=DAISY\0\0\0\0\0\0
。
このようなちょっとした暗号操作には、Pythonのトップレベルとパイクリプト図書館。
>>> from binascii import hexlify, unhexlify
>>> from Crypto.Cipher import AES
>>> ciphertext = unhexlify('FC 89 BF C2 B0 5F 1C 2E 64 B8 78 43 92 78 3A C9'.replace(' ', ''))
>>> key = 'REDRYDER'.ljust(16, '\0')
>>> AES.new(key, AES.MODE_ECB).decrypt(ciphertext)
'FLAG=DAISY\x00\x00\x00\x00\x00\x00'
答え2
これは機能します:
echo '0: FC89BFC2B05F1C2E64B8784392783AC9' | xxd -r | openssl enc -aes-128-ecb -d -nopad -nosalt -K 5245445259444552
-k オプションの入力は理解できませんが、プレーンテキスト キーを 16 進数 (適切なバイト順序) に変換し、代わりに -K を使用すると機能します。
openssl はブードゥーです!