コンテンツにスキップ

pytilpack.pycrypto

必要なextra

pip install pytilpack[pycryptodome]

pytilpack.pycrypto

pycryptodomeによるAES-GCM暗号化/復号ユーティリティ。

キーおよび暗号文はBASE64エンコードした文字列で扱う。 nonceはデフォルトで12バイトとし、暗号文の先頭に付加する前提とする。

DEFAULT_KEY_SIZE = 32 module-attribute

デフォルトのキーサイズ(バイト単位)

create_key(nbytes=DEFAULT_KEY_SIZE, url_safe=False)

ランダムなキーを生成する。デフォルトは32バイト。

ソースコード位置: pytilpack/pycrypto.py
def create_key(nbytes: int = DEFAULT_KEY_SIZE, url_safe: bool = False) -> str:
    """ランダムなキーを生成する。デフォルトは32バイト。"""
    return pytilpack.base64.encode(secrets.token_bytes(nbytes), url_safe=url_safe)

encrypt_json(obj, key, url_safe=False)

オブジェクトをJSON文字列化してから暗号化する。

ソースコード位置: pytilpack/pycrypto.py
def encrypt_json(obj: typing.Any, key: str | bytes, url_safe: bool = False) -> str:
    """オブジェクトをJSON文字列化してから暗号化する。"""
    return encrypt(json.dumps(obj), key, url_safe=url_safe)

decrypt_json(s, key, url_safe=False)

復号してからJSONとして解析する。

ソースコード位置: pytilpack/pycrypto.py
def decrypt_json(s: str, key: str | bytes, url_safe: bool = False) -> typing.Any:
    """復号してからJSONとして解析する。"""
    return json.loads(decrypt(s, key, url_safe=url_safe))

encrypt(plaintext, key, url_safe=False)

AES-GCMで暗号化する。

ソースコード位置: pytilpack/pycrypto.py
def encrypt(plaintext: str, key: str | bytes, url_safe: bool = False) -> str:
    """AES-GCMで暗号化する。"""
    if isinstance(key, str):
        key = pytilpack.base64.decode(key, url_safe=url_safe)
    plaintext_bytes = plaintext.encode("utf-8")
    nonce = secrets.token_bytes(12)
    cipher = Crypto.Cipher.AES.new(key, Crypto.Cipher.AES.MODE_GCM, nonce=nonce)
    ct, tag = cipher.encrypt_and_digest(plaintext_bytes)
    ciphertext = nonce + ct + tag
    ciphertext = pytilpack.base64.encode(ciphertext, url_safe=url_safe)
    return ciphertext

decrypt(ciphertext, key, url_safe=False)

AES-GCMで復号する。

ソースコード位置: pytilpack/pycrypto.py
def decrypt(ciphertext: str, key: str | bytes, url_safe: bool = False) -> str:
    """AES-GCMで復号する。"""
    if isinstance(key, str):
        key = pytilpack.base64.decode(key, url_safe=url_safe)
    cipherbytes = pytilpack.base64.decode(ciphertext, url_safe=url_safe)
    nonce, ct, tag = cipherbytes[:12], cipherbytes[12:-16], cipherbytes[-16:]
    cipher = Crypto.Cipher.AES.new(key, Crypto.Cipher.AES.MODE_GCM, nonce=nonce)
    plaintext = cipher.decrypt_and_verify(ct, tag)
    return plaintext.decode("utf-8")