0
2

pythonでAES暗号化する方法:②Crypto編

Posted at

やりたいこと

pythonでAES(共通鍵方式)でパスワードの暗号化・複号化したい

前提

・Pythonインストール済み
・PyCryptodome インストール済み

※Cryptoは以前はcryptoライブラリで動いてたのですが、2024/01現時点では、cryptoではもう動けないらしくて、PyCryptodomeでやりました。

※すでにcryptoを入れてる人は、cryptoをアンインストールしないとうまくいけないので、エラーで落ちたらcryptoをアンインストールしてください

やり方

さっそく調べた内容をソースコードで作りました

CryptoのAESは128, 192, 256 bitなどの鍵を生成でき、CBCやECBなどいろんなモードを対応できるようです。

今回はCBCモードを採用しました!

暗号化複号化するときは、パラメータはbyte形式じゃないとだめなので、b64encodeへ変換しました・

qiita.rb
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)

image.png

終わりに

暗号化された値はFernetのやつより短いですね。。。

参照サイト

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2