Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
18
Help us understand the problem. What is going on with this article?
@Azunyan1111

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

More than 3 years have 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
18
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Azunyan1111
#seccamp 18 18Y 16F/Golang/Webセキュリティ/元ゲーム会社
naxa
動画関連サービスの技術支援、開発、コンサルティングを行っています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
18
Help us understand the problem. What is going on with this article?