🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

暗号化

ネットワークを通じてデジタルデータをやり取りする際に、第三者に解読されることのないよう、アルゴリズムを用いてデータを変換すること。

ハッシュ

ハッシュは、高速にデータ検索を行うアルゴリズムのことです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

4339閲覧

AES暗号の復号について

ppon

総合スコア2

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

暗号化

ネットワークを通じてデジタルデータをやり取りする際に、第三者に解読されることのないよう、アルゴリズムを用いてデータを変換すること。

ハッシュ

ハッシュは、高速にデータ検索を行うアルゴリズムのことです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/03/11 06:43

前提・実現したいこと

・AES暗号(ECBモード、iv無し、鍵は「piyo」という文字列のSHA-1ハッシュの最初の16バイト)で暗号化された文字列をBase64でエンコードしたものをpython3で復号したく、以下のようなスクリプトを書きましたがうまく復号できません。
・復号時に渡すKeyがHEX値ではなく、str型になっているのが原因なのかと思っていますが、解決方法が分からず質問をさせていただきました。

該当のソースコード

Python3

1 2from Crypto.Cipher import AES 3import hashlib 4import base64 5 6C = "Nzk1MTkxZDc0ZmYzY2ZjNjdlNTQ4MDQwNjJlMDE4MTY="   //平文「hoge」をAES-ECBで暗号化してBase64化したもの。 7 8K = hashlib.sha1(b'piyo').hexdigest() 9Key = K[:32] 10 11 12aes = AES.new(Key, AES.MODE_ECB) 13dec = aes.decrypt(base64.b64decode(C)) 14print(dec)

実行結果

單廡ナ謦チqコ毎マェュg・FヨI・&7s鵡m

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bsdfan

2021/03/12 02:29

Cが、『平文「hoge」をAES-ECBで暗号化してBase64化したもの』ではなく、 『平文「hoge」をAES-ECBで暗号化して、16進数の文字列に変換して、Base64化したもの』なのでは?
ppon

2021/03/12 04:27

ご指摘ありがとうございます。 bsdfhanさんの仰る通りで、別の方が作成していただいたスクリプトで解決致しました。 貴重な情報をありがとうございました。
guest

回答2

0

ベストアンサー

でっちあげました。

>>> from Crypto.Cipher import AES >>> import hashlib >>> import base64 >>> >>> C = "Nzk1MTkxZDc0ZmYzY2ZjNjdlNTQ4MDQwNjJlMDE4MTY=" >>> >>> K = hashlib.sha1(b'piyo').hexdigest() >>> Key = bytes.fromhex(K[:32]) >>> >>> aes = AES.new(Key, AES.MODE_ECB) >>> >>> >>> aes = AES.new(Key, AES.MODE_ECB) >>> dec = unpad(aes.decrypt(bytes.fromhex(base64.b64decode(C).decode())), 16).decode() >>> print(dec) hoge

以下は関係ないので忘れてください。

暗号について、少し調べてみました。

AESはブロック暗号でブロック長は128ビット=16バイトです。
したがって暗号化されたデータは16バイトの整数倍になります。

python

1>>> C = "Nzk1MTkxZDc0ZmYzY2ZjNjdlNTQ4MDQwNjJlMDE4MTY=" 2>>> len(C) 344

ですので、CはAES暗号化されたデータではないようです。

暗号化と復号化の例を作ってみましたので、これを見て考えてください。

python

1from Crypto.Cipher import AES 2import hashlib 3import base64 4from Crypto.Util.Padding import pad, unpad 5 6K = hashlib.sha1(b'piyo').hexdigest() 7Key = bytes.fromhex(K[:32]) 8 9aes = AES.new(Key, AES.MODE_ECB) 10 11 12BLOCK_SIZE = 16 13src_s = '吾輩は猫である。名前はまだ無い。 どこで生れたかとんと 見当 がつかぬ。' 14print(len(src_s)) 15src_encode = src_s.encode('utf-8') 16print(src_encode) 17print(len(src_encode)) 18src_encode_b64 = base64.b64encode(src_encode) 19print(src_encode_b64) 20print(len(src_encode_b64)) 21src_encode_b64_aes = aes.encrypt(pad(src_encode_b64, BLOCK_SIZE)) 22print(src_encode_b64_aes) 23print(len(src_encode_b64_aes)) 24tgt_encode_b64 = aes.decrypt(src_encode_b64_aes) 25print(tgt_encode_b64) 26print(len(tgt_encode_b64)) 27tgt_encode = base64.b64decode(tgt_encode_b64) 28print(tgt_encode) 29print(len(tgt_encode)) 30tgt_s = tgt_encode.decode('utf-8') 31print(tgt_s)

実行結果

python

1>>> src_s = '吾輩は猫である。名前はまだ無い。 どこで生れたかとんと 見当 がつかぬ。' 2>>> print(len(src_s)) 336 4>>> src_encode = src_s.encode('utf-8') 5>>> print(src_encode) 6b'\xe5\x90\xbe\xe8\xbc\xa9\xe3\x81\xaf\xe7\x8c\xab\xe3\x81\xa7\xe3\x81\x82\xe3\x82\x8b\xe3\x80\x82\xe5\x90\x8d\xe5\x89\x8d\xe3\x81\xaf\xe3\x81\xbe\xe3\x81\xa0\xe7\x84\xa1\xe3\x81\x84\xe3\x80\x82 \xe3\x81\xa9\xe3\x81\x93\xe3\x81\xa7\xe7\x94\x9f\xe3\x82\x8c\xe3\x81\x9f\xe3\x81\x8b\xe3\x81\xa8\xe3\x82\x93\xe3\x81\xa8 \xe8\xa6\x8b\xe5\xbd\x93 \xe3\x81\x8c\xe3\x81\xa4\xe3\x81\x8b\xe3\x81\xac\xe3\x80\x82' 7>>> print(len(src_encode)) 8102 9>>> src_encode_b64 = base64.b64encode(src_encode) 10>>> print(src_encode_b64) 11b'5ZC+6Lyp44Gv54yr44Gn44GC44KL44CC5ZCN5YmN44Gv44G+44Gg54Sh44GE44CCIOOBqeOBk+OBp+eUn+OCjOOBn+OBi+OBqOOCk+OBqCDopovlvZMg44GM44Gk44GL44Gs44CC' 12>>> print(len(src_encode_b64)) 13136 14>>> src_encode_b64_aes = aes.encrypt(pad(src_encode_b64, BLOCK_SIZE)) 15>>> print(src_encode_b64_aes) 16b'lW7n\x91\t\xd3\xcaR\x04\x8a\xd6Vr_\xb6\xea\x04\x91\xa7\xb6\xfeV\x8b3\x11\x94\xdf\x0f\nyT\xd4#\xa7\x96C\xb4\xe3P\x92\x9c\xaf\xe6Ol\x95P\x8a\xcbK\xac\xaf{#_\x8c\x16\x99\x89N,\xb2\x06\x8e\xe4<Y\xbe\xa3w,\x0f\x8b\xc8\x0c\x17F \xca\t\x11:\xc5{Nx56C\xef.\xcc\xfb\xbcr\xd81\xe9a\xb7X\x93\xa9`\xcd\'\x1b0a\x1a\x17\x7f\x94\xa3S\x1a\x12M\xaa\xb9\xc0\xfe\xfd\x8c\xe4\x7f\xc9\xbe\x1d AYB.\x8a\xe71\xb5Mj"t\xfd' 17>>> print(len(src_encode_b64_aes)) 18144 19>>> tgt_encode_b64 = aes.decrypt(src_encode_b64_aes) 20>>> print(tgt_encode_b64) 21b'5ZC+6Lyp44Gv54yr44Gn44GC44KL44CC5ZCN5YmN44Gv44G+44Gg54Sh44GE44CCIOOBqeOBk+OBp+eUn+OCjOOBn+OBi+OBqOOCk+OBqCDopovlvZMg44GM44Gk44GL44Gs44CC\x08\x08\x08\x08\x08\x08\x08\x08' 22>>> print(len(tgt_encode_b64)) 23144 24>>> tgt_encode = base64.b64decode(tgt_encode_b64) 25>>> print(tgt_encode) 26b'\xe5\x90\xbe\xe8\xbc\xa9\xe3\x81\xaf\xe7\x8c\xab\xe3\x81\xa7\xe3\x81\x82\xe3\x82\x8b\xe3\x80\x82\xe5\x90\x8d\xe5\x89\x8d\xe3\x81\xaf\xe3\x81\xbe\xe3\x81\xa0\xe7\x84\xa1\xe3\x81\x84\xe3\x80\x82 \xe3\x81\xa9\xe3\x81\x93\xe3\x81\xa7\xe7\x94\x9f\xe3\x82\x8c\xe3\x81\x9f\xe3\x81\x8b\xe3\x81\xa8\xe3\x82\x93\xe3\x81\xa8 \xe8\xa6\x8b\xe5\xbd\x93 \xe3\x81\x8c\xe3\x81\xa4\xe3\x81\x8b\xe3\x81\xac\xe3\x80\x82' 27>>> print(len(tgt_encode)) 28102 29>>> tgt_s = tgt_encode.decode('utf-8') 30>>> print(tgt_s) 31吾輩は猫である。名前はまだ無い。 どこで生れたかとんと 見当 がつかぬ。

投稿2021/03/11 12:53

編集2021/03/11 14:46
ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ppon

2021/03/11 14:02

ご回答ありがとうございます。 また、サンプルまでお作りいただいて大変勉強になりました!重ねてお礼申し上げます。 残念ながらまだ解決には至っていません。 ご指摘いただいた「暗号化されたデータは16バイトの整数倍になるので、CはAES暗号化されたデータではないようです」という点についてですが、hogeをAESで暗号化した時点で値は「795191d74ff3cfc67e54804062e01816」と16バイトになっており、この値をBase64にすることで、コードに記載しているCの値になります。 なので、Cの値をbase64でデコードした上でAESで復号をすれば平文が出てくるはずで、「CyberChef」というWEBサイトで試すと平文hogeが表示されるのです。。。 しかし、私はこれをPythonで書きたいので頭を悩ませているところです。 もしまた何かありましたらご教示いただけますと幸いです。 よろしくお願いいたします。
ppaul

2021/03/11 14:47 編集

最適かどうかはわかりませんが、一応動作するコードをでっちあげました。
ppon

2021/03/12 04:26

こちらでも動作を確認しました。 スクリプトの作成までしていただいて本当に感謝しております!!! 別の方からもご指摘があったとおりCが『平文「hoge」をAES-ECBで暗号化して、16進数の文字列に変換して、Base64化したもの』になっていたのですね。 大変勉強になりました。今後とのよろしくお願いいたします。
guest

0

試してないですが、

python

1Key = hashlib.sha1(b'piyo').digest()[:16]

なのでは。

投稿2021/03/11 06:52

int32_t

総合スコア21679

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ppon

2021/03/11 06:57

ご回答ありがとうございます。 ご指摘頂いたとおりに変更してみましたが、うまく復号できませんでした。申し訳ありません。。 実行結果 ``` 拭秉Tケ!T]uワ・誹ラーニ。KvJRU葮 ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問