やりたいこと
pythonでAES(共通鍵方式)でパスワードの暗号化・複号化したい
前提
・Pythonインストール済み
・PyCryptodome インストール済み
※Cryptoは以前はcryptoライブラリで動いてたのですが、2024/01現時点では、cryptoではもう動けないらしくて、PyCryptodomeでやりました。
※すでにcryptoを入れてる人は、cryptoをアンインストールしないとうまくいけないので、エラーで落ちたらcryptoをアンインストールしてください
やり方
さっそく調べた内容をソースコードで作りました
CryptoのAESは128, 192, 256 bitなどの鍵を生成でき、CBCやECBなどいろんなモードを対応できるようです。
今回はCBCモードを採用しました!
暗号化複号化するときは、パラメータはbyte形式じゃないとだめなので、b64encodeへ変換しました・
from base64 import b64encode, b64decode
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
# 鍵の作成
def create_key():
key = get_random_bytes(16)
return b64encode(key).decode('utf-8')
# 暗号化する
def encrypt(key, data):
key = b64decode(key)
data = bytes(data, 'utf-8')
cipher = AES.new(key, AES.MODE_CBC)
ct_bytes = cipher.encrypt(pad(data, AES.block_size))
iv = b64encode(cipher.iv).decode('utf-8')
ct = b64encode(ct_bytes).decode('utf-8')
return ct, iv
# 復号化する
def decrypt(key, iv, ct):
key = b64decode(key)
iv = b64decode(iv)
ct = b64decode(ct)
cipher = AES.new(key, AES.MODE_CBC, iv)
pt = unpad(cipher.decrypt(ct), AES.block_size)
return pt.decode('utf-8')
password = 'password'
# 新しい鍵の作成
key = create_key()
# 新しい鍵のprint
print(key)
# 暗号化する
ct, iv = encrypt(key, password)
# 暗号化したパスワードのprint
print(ct)
# hash値のprint
print(iv)
# 復号化する
pt = decrypt(key, iv, ct)
# 結果確認のため、復号したものをprint
print(pt)
前回試したFernetと異なったのは、keyだけでなく、ivというHASH値みたいなものが暗号化複号化するとき必要となります。。。(二重鍵みたいなイメージかな)
keyとivは毎回同じものを生成しなくても大丈夫なので、以前作ったやつを覚えて流用するのはOkということです。
実際実行した結果はこちらです。
上から下は、鍵(str)、暗号化したパス(str)、iv(str)、複号化したパス(str)
終わりに
暗号化された値はFernetのやつより短いですね。。。
参照サイト