Edited at

【Python】pycryptoで投げるたけでAES暗号化復号してくれる関数作った。

More than 1 year has passed since last update.

できること

・平文・パスワード・ベクトルを引数に入れて実行するとbase64形式で暗号化されたデータを返す。

・同様に平文をbase64形式で暗号化されたデータに差し替えて実行すると平文を返す。

AES暗号化の条件

鍵は16バイト,24バイト,32バイトのうちのいずれかの長さにしなければならない。

平文は16バイトの倍数の長さにしなければならない。

ivを使用して、推測されにくくする。

ivに関しては一つのアプリケーションに対して同一のものを使うのが適切かと思います。

コピペして使っても大丈夫だとは思うが、AESの理解が完全ではないため正しいコードかは保証できない。

脆弱性があるならコメントでご指摘をお願いします。

インストールは

$ pip install pycrypto

暗号化


get_encrypt_data.py


from Crypto.Cipher import AES
import hashlib
import base64

def get_encrypt_data(raw_data, key, iv):
raw_data_base64 = base64.b64encode(raw_data)
# 16byte
if len(raw_data_base64) % 16 != 0:
raw_data_base64_16byte = raw_data_base64
for i in range(16 - (len(raw_data_base64) % 16)):
raw_data_base64_16byte += "_"
else:
raw_data_base64_16byte = raw_data_base64
secret_key = hashlib.sha256(key).digest()
iv = hashlib.md5(iv).digest()
crypto = AES.new(secret_key, AES.MODE_CBC, iv)
cipher_data = crypto.encrypt(raw_data_base64_16byte)
cipher_data_base64 = base64.b64encode(cipher_data)
return cipher_data_base64


引数に平文データ。鍵。ベクトル。

まず最初にbase64に変える(2バイト文字でも画像でもokにするため)

次に暗号化文は16ビットの倍数にしなければならないため、

基本的にbase64で使用しない"_"をケツに補完して16ビットの倍数に直す。

16バイトの倍数ならそのまま

鍵をsha256で32ビット長に変える。

ベクトルをMD5で16ビット長に変える。

暗号化して、送信しやすいようにbase64に変換してし返す。

復号


get_decrypt_data.py


from Crypto.Cipher import AES
import hashlib
import base64

def get_decrypt_data(cipher_data_base64, key, iv):
cipher_data = base64.b64decode(cipher_data_base64)
secret_key = hashlib.sha256(key).digest()
iv = hashlib.md5(iv).digest()
crypto = AES.new(secret_key, AES.MODE_CBC, iv)
raw_data_base64_16byte = crypto.decrypt(cipher_data)
raw_data_base64 = raw_data_base64_16byte.split("_")[0]
raw_data = base64.b64decode(raw_data_base64)
return raw_data


引数にbase64に変換された暗号データ。鍵。ベクトル。

まず最初にbase64に変換された暗号データを暗号データに直す。

次に鍵をsha256で32ビットに変える。

復号して、split("_")[0]で有効なbase64だけを取り出して変換後リターンで返す。

実行結果


main.py

if __name__ == "__main__":

message = "114514"
password = "This is password"
iv = "hoge"
encrypt_data = get_encrypt_data(message, password, iv)
print encrypt_data
decrypt_data = get_decrypt_data(encrypt_data, password, iv)
print decrypt_data


cmd.sh

$ r64FMFs04APfNQo2d6uFpQ==

$ 114514