Skip to content

AES加解密 in Python

依赖环境

toml
[tool.poetry.dependencies]
python = "^3.9"
pycryptodome = "^3.19.1"

代码

python
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
from base64 import b64encode, b64decode

class AES_CBC_256:

    def __init__(self):
        self.iv = get_random_bytes(16)

    def encrypt(self, key: bytes, iv: bytes, plaintext: bytes) -> bytes:
        plaintext = pad(plaintext, AES.block_size)
        cipher = AES.new(key, AES.MODE_CBC, iv=iv)
        ciphertext = cipher.encrypt(plaintext)
        return ciphertext

    def encrypt_as_b64(self, key: bytes, plaintext: str) -> str:
        iv = self.iv
        ciphertext = self.encrypt(key, iv, plaintext.encode())
        return b64encode(iv + ciphertext).decode()

    def decrypt(self, key: bytes, iv: bytes, ciphertext: bytes) -> bytes:
        cipher = AES.new(key, AES.MODE_CBC, iv=iv)
        decrypted_text = unpad(cipher.decrypt(ciphertext), AES.block_size)
        return decrypted_text

    def decrypt_as_text(self, key: bytes, ciphertext: str) -> str:
        ciphertext = b64decode(ciphertext)
        iv = ciphertext[:16]
        ciphertext = ciphertext[16:]
        return self.decrypt(key, iv, ciphertext).decode()

key = "abcdabcdabcdabcd"  # Use a secure key for AES-256
key = key[:32].encode()   # 32 bytes for AES-256

plaintext = "{}"

print('PlainText:', plaintext)

aes_cbc_256 = AES_CBC_256()
ciphertext = aes_cbc_256.encrypt_as_b64(key, plaintext)
print(f"Encrypted: {ciphertext}")

decrypted_text = aes_cbc_256.decrypt_as_text(key, ciphertext)
print(f"Decrypted: {decrypted_text}")
python
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from base64 import b64encode, b64decode

class AES_CBC_256:

    def __init__(self):
        pass

    def encrypt(self, key: bytes, iv: bytes, plaintext: bytes) -> bytes:
        cipher = AES.new(key, AES.MODE_CBC, iv=iv)
        padded_plaintext = pad(plaintext, AES.block_size)
        ciphertext = cipher.encrypt(padded_plaintext)
        return ciphertext

    def decrypt(self, key: bytes, iv: bytes, cipher_code: bytes) -> bytes:
        cipher = AES.new(key, AES.MODE_CBC, iv=iv)
        decrypted = cipher.decrypt(cipher_code)

        try:
            decrypted = unpad(decrypted, AES.block_size)
        except:
            pass

        return decrypted

    def encrypt_as_text(self, key: bytes, iv: bytes, plaintext: str) -> str:
        plaintext_bytes = plaintext.encode()
        ciphertext = self.encrypt(key, iv, plaintext_bytes)
        return b64encode(ciphertext).decode()

    def decrypt_as_text(self, key: bytes, iv: bytes, ciphertext: str) -> str:
        ciphertext = b64decode(ciphertext.encode())
        return self.decrypt(key, iv, ciphertext).decode()


# custom demo

from hashlib import md5

def gen_key_and_iv(token):

    def md5_hex(key: bytes) -> str:
        return md5(key).hexdigest()[:16]

    key = token[:16].encode()
    iv = md5_hex(key)[:16].encode()

    assert len(key) == 16
    assert len(iv) == 16

    print('[*]', 'key', key)
    print('[*]', 'iv', iv)
    return key, iv


token = 'abcdabcdabcdabcd'
plaintext = '{}'

print('PlainText:', plaintext)

key, iv = gen_key_and_iv(token)
aes_cbc_256 = AES_CBC_256()

ciphertext = aes_cbc_256.encrypt_as_text(key, iv, plaintext)
print('EncryptedText:', ciphertext)

decrypted_text = aes_cbc_256.decrypt_as_text(key, iv, ciphertext)
print(f"Decrypted: {decrypted_text}")

Released under the MIT License.