[참고 - Docs]

https://pycryptodome.readthedocs.io/en/latest/src/cipher/aes.html

 

[MODE_EAX]

# pip install pycryptodome
import base64

from Crypto.Cipher import AES


class AES256:
    def __init__(self, key: str):
        self.key = base64.b64decode(key.encode())
        pass

    def encrypt(self, plain_text: str):
        """AES256 암호화

        Returns:
            * tuple (cipher_text, tag, nonce)
        """
        cipher = AES.new(key=self.key, mode=AES.MODE_EAX)
        nonce = cipher.nonce
        cipher_text, tag = cipher.encrypt_and_digest(plain_text.encode())
        return cipher_text, tag, nonce

    def get_encrypted(self, plain_text: str) -> str:
        """AES256 암호화된 데이터를 문자열로 반환"""
        cipher_text = self.encrypt(plain_text=plain_text)[0]
        return base64.b64encode(cipher_text).decode()

    def decrypt(
        self,
        cipher_text: bytes,
        nonce: bytes,
        tag: bytes,
    ):
        cipher = AES.new(self.key, AES.MODE_EAX, nonce=nonce)
        plain_text = cipher.decrypt(cipher_text)
        try:
            cipher.verify(tag)
            return plain_text.decode()
        except Exception as e:
            print(f"aes256 decode error: {e}")
            return False

[실습]

import base64
from uuid import uuid4

aes256 = AES256("key")

cipher_text, tag, nonce = aes256.encrypt("plaintext")
print(f"cipher_text: {cipher_text}")
print(f"b64: {base64.b64encode(cipher_text).decode()}")

result = aes256.decrypt(cipher_text=cipher_text, nonce=nonce, tag=tag)
print(f"result: {result}")  # plaintext

 

[MODE_CBC]

import binascii
from base64 import b64decode, b64encode

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

from ..configs import settings


class AES256_MODE_CBC:
    def __init__(self, password):
        self.cipher_pass = password
        self.transformation = "AES/CBC/PKCS5Padding"
        self.iv = bytes([0] * 16)

        sk = self.to_hex_string(self.cipher_pass.encode())
        key_data = self.to_bytes(sk, 16)
        self.key = self.generate_key("AES", key_data)

    def encrypt(self, encrypt_str):
        cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
        plain_bytes = encrypt_str.encode("utf-8")
        encrypted_bytes = cipher.encrypt(pad(plain_bytes, AES.block_size))
        return b64encode(encrypted_bytes).decode("utf-8")

    def decrypt(self, decrypt_str):
        cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
        decrypted_bytes = cipher.decrypt(b64decode(decrypt_str))
        plain_text = unpad(decrypted_bytes, AES.block_size).decode("utf-8")
        return plain_text

    def generate_key(self, algorithm, key_data):
        if algorithm == "AES":
            return key_data
        raise ValueError("Unsupported algorithm")

    def to_hex_string(self, byte_data):
        return binascii.hexlify(byte_data).decode()

    def to_bytes(self, hex_str, radix):
        if radix != 16:
            raise ValueError(f"Unsupported radix: {radix}")
        return bytes.fromhex(hex_str)


aes256_mode_cbc = AES256_MODE_CBC(settings.NICE_EPAY_SECRET_KEY)

+ Recent posts