在 Python 中处理 ECB(Electronic Codebook,电子密码本模式) 通常涉及对称加密算法(如 AES),但需要特别强调的是:
⚠️ ECB 模式是不安全的,因为它对相同的明文块生成相同的密文块,无法隐藏数据模式,仅用于学习或测试,切勿用于生产环境,推荐使用 CBC、CTR、GCM 等更安全的模式。
使用 pycryptodome 库实现 AES-ECB
安装依赖
pip install pycryptodome
加密示例
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
def aes_ecb_encrypt(plaintext: str, key: bytes) -> bytes:
"""
使用 AES-ECB 模式加密
:param plaintext: 明文字符串
:param key: 16/24/32 字节的密钥
:return: Base64 编码的密文
"""
if len(key) not in (16, 24, 32):
raise ValueError("密钥长度必须为 16、24 或 32 字节")
cipher = AES.new(key, AES.MODE_ECB)
padded_data = pad(plaintext.encode('utf-8'), AES.block_size)
ciphertext = cipher.encrypt(padded_data)
return base64.b64encode(ciphertext)
def aes_ecb_decrypt(ciphertext_b64: str, key: byt
es) -> str:
"""
使用 AES-ECB 模式解密
:param ciphertext_b64: Base64 编码的密文
:param key: 16/24/32 字节的密钥
:return: 解密后的明文
"""
if len(key) not in (16, 24, 32):
raise ValueError("密钥长度必须为 16、24 或 32 字节")
ciphertext = base64.b64decode(ciphertext_b64)
cipher = AES.new(key, AES.MODE_ECB)
padded_plaintext = cipher.decrypt(ciphertext)
plaintext = unpad(padded_plaintext, AES.block_size)
return plaintext.decode('utf-8')
# 示例使用
if __name__ == "__main__":
key = b'0123456789abcdef' # 16 字节密钥(AES-128)
message = "Hello, ECB Mode!"
encrypted = aes_ecb_encrypt(message, key)
print(f"加密结果 (Base64): {encrypted.decode('utf-8')}")
decrypted = aes_ecb_decrypt(encrypted.decode('utf-8'), key)
print(f"解密结果: {decrypted}")
使用 cryptography 库(不直接支持 ECB,需手动实现)
注意:
cryptography库出于安全考虑,默认不提供 ECB 模式,如需使用,需借助底层Cipher并指定mode=ECB(部分版本支持)。
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend from Crypto.Util.Padding import pad, unpad # 仍需 pycryptodome 用于填充 import base64 def aes_ecb_encrypt_cryptography(plaintext: str, key: bytes) -> bytes: if len(key) not in (16, 24, 32): raise ValueError("密钥长度必须为 16、24 或 32 字节") padded_data = pad(plaintext.encode('utf-8'), 16) cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend()) encryptor = cipher.encryptor() ciphertext = encryptor.update(padded_data) + encryptor.finalize() return base64.b64encode(ciphertext) def aes_ecb_decrypt_cryptography(ciphertext_b64: str, key: bytes) -> str: if len(key) not in (16, 24, 32): raise ValueError("密钥长度必须为 16、24 或 32 字节") ciphertext = base64.b64decode(ciphertext_b64) cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend()) decryptor = cipher.decryptor() padded_plaintext = decryptor.update(ciphertext) + decryptor.finalize() plaintext = unpad(padded_plaintext, 16) return plaintext.decode('utf-8')
重要提醒
| 项目 | 说明 |
|---|---|
| 安全性 |
ECB 不推荐用于任何实际应用场景 |
| 替代方案 | 使用 AES.MODE_CBC、AES.MODE_CTR 或 AES.MODE_GCM |
| 密钥管理 | 密钥应安全存储,避免硬编码 |
| 填充方式 | 使用 Crypto.Util.Padding 进行 PKCS7 填充 |
更安全的替代示例(AES-GCM)
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
import base64
def aes_gcm_encrypt(plaintext: str, key: bytes) -> tuple:
"""返回 (nonce, ciphertext, tag)"""
cipher = AES.new(key, AES.MODE_GCM)
ciphertext, tag = cipher.encrypt_and_digest(plaintext.encode('utf-8'))
return cipher.nonce, ciphertext, tag
def aes_gcm_decrypt(nonce: bytes, ciphertext: bytes, tag: bytes, key: bytes) -> str:
cipher = AES.new(key, AES.MODE_GCM, nonce=nonce)
plaintext = cipher.decrypt_and_verify(ciphertext, tag)
return plaintext.decode('utf-8')
# 使用示例
key = get_random_bytes(32) # 256 位密钥
nonce, ct, tag = aes_gcm_encrypt("Secure message", key)
decrypted = aes_gcm_decrypt(nonce, ct, tag, key)
print(f"解密: {decrypted}")
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/480978.html



