如何利用PyCryptodome模块在Python中对敏感数据进行AES加密?

2026-04-30 10:462阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计795个文字,预计阅读时间需要4分钟。

如何利用PyCryptodome模块在Python中对敏感数据进行AES加密?

由于AES是分组加密算法,原始明文长度必须是16字节(AES-128)的整数倍,且不能直接处理任意字符字符串。常见错误是输入UTF-8字符串后报错ValueError: Data must be a multiple of block length。正确做法是:

PyCryptodome 不提供自动填充,得自己补。推荐用 PKCS#7 填充(注意不是 PKCS#5,虽然对 AES 来说二者等价):

from Crypto.Util.Padding import pad, unpad from Crypto.Cipher import AES <p>key = b'0123456789abcdef' # 16字节密钥 data = b'secret message' padded = pad(data, AES.block_size) # 补到16/24/32字节对齐 cipher = AES.new(key, AES.MODE_CBC) ciphertext = cipher.encrypt(padded)

AES.MODE_CBC 必须配随机 iv,别硬编码

CBC 模式下,相同的明文+密钥总会生成相同密文,这会暴露数据模式(比如大量重复的“STATUS:OK”)。攻击者可能通过观察密文长度和重复性推测内容。所以每次加密都必须用新 iv,且要和密文一起保存或传输。

别写 iv = b'1234567890123456' —— 这等于没加 IV。正确做法:

立即学习“Python免费学习笔记(深入)”;

  • iv = get_random_bytes(16)(需 from Crypto.Random import get_random_bytes
  • 加密时:用该 iv 初始化 AES.new(key, AES.MODE_CBC, iv)
  • 解密时:必须用**同一个** iv,通常把 iv 放在密文前 16 字节(如 iv + ciphertext),解密时切出来

密钥长度不匹配会导致 ValueError: Invalid key size

AES 只接受 128/192/256 位密钥,也就是 16/24/32 字节的 bytes。常见错误包括:

  • 用字符串当密钥:key = "mykey123" → 错,必须是 b"mykey123""mykey123".encode()
  • 密钥太短:如 8 字节 → 报错,不能自动补零
  • 从口令派生密钥?别手写哈希,用 scryptPBKDF2from Crypto.Protocol.KDF import scrypt,否则弱口令=弱密钥

敏感数据加密后别存成裸 bytes,优先转 base64

二进制密文含不可见、不可打印字符(比如 \x00、\xff),直接写入 JSON / CSV / 日志会出错或截断。常见现象是解密时报 ValueError: Padding is incorrect,实际是传输过程损坏了字节流。

解决方案很简单:

import base64 encoded = base64.b64encode(iv + ciphertext).decode('ascii') # 得到字符串 # 存库、传 API、写文件都用这个字符串 <h1>解密时反向:</h1><p>raw = base64.b64decode(encoded) iv, ct = raw[:16], raw[16:] cipher = AES.new(key, AES.MODE_CBC, iv) plain = unpad(cipher.decrypt(ct), AES.block_size)

IV 和密文必须一起 base64 编码,否则无法分离。

记住:AES 本身不解决密钥管理、完整性校验(别漏 HMAC)、密钥轮换这些事。如果数据要长期存储或跨服务共享,光靠 AES.MODE_CBC + 手动 padding 是不够稳健的。

本文共计795个文字,预计阅读时间需要4分钟。

如何利用PyCryptodome模块在Python中对敏感数据进行AES加密?

由于AES是分组加密算法,原始明文长度必须是16字节(AES-128)的整数倍,且不能直接处理任意字符字符串。常见错误是输入UTF-8字符串后报错ValueError: Data must be a multiple of block length。正确做法是:

PyCryptodome 不提供自动填充,得自己补。推荐用 PKCS#7 填充(注意不是 PKCS#5,虽然对 AES 来说二者等价):

from Crypto.Util.Padding import pad, unpad from Crypto.Cipher import AES <p>key = b'0123456789abcdef' # 16字节密钥 data = b'secret message' padded = pad(data, AES.block_size) # 补到16/24/32字节对齐 cipher = AES.new(key, AES.MODE_CBC) ciphertext = cipher.encrypt(padded)

AES.MODE_CBC 必须配随机 iv,别硬编码

CBC 模式下,相同的明文+密钥总会生成相同密文,这会暴露数据模式(比如大量重复的“STATUS:OK”)。攻击者可能通过观察密文长度和重复性推测内容。所以每次加密都必须用新 iv,且要和密文一起保存或传输。

别写 iv = b'1234567890123456' —— 这等于没加 IV。正确做法:

立即学习“Python免费学习笔记(深入)”;

  • iv = get_random_bytes(16)(需 from Crypto.Random import get_random_bytes
  • 加密时:用该 iv 初始化 AES.new(key, AES.MODE_CBC, iv)
  • 解密时:必须用**同一个** iv,通常把 iv 放在密文前 16 字节(如 iv + ciphertext),解密时切出来

密钥长度不匹配会导致 ValueError: Invalid key size

AES 只接受 128/192/256 位密钥,也就是 16/24/32 字节的 bytes。常见错误包括:

  • 用字符串当密钥:key = "mykey123" → 错,必须是 b"mykey123""mykey123".encode()
  • 密钥太短:如 8 字节 → 报错,不能自动补零
  • 从口令派生密钥?别手写哈希,用 scryptPBKDF2from Crypto.Protocol.KDF import scrypt,否则弱口令=弱密钥

敏感数据加密后别存成裸 bytes,优先转 base64

二进制密文含不可见、不可打印字符(比如 \x00、\xff),直接写入 JSON / CSV / 日志会出错或截断。常见现象是解密时报 ValueError: Padding is incorrect,实际是传输过程损坏了字节流。

解决方案很简单:

import base64 encoded = base64.b64encode(iv + ciphertext).decode('ascii') # 得到字符串 # 存库、传 API、写文件都用这个字符串 <h1>解密时反向:</h1><p>raw = base64.b64decode(encoded) iv, ct = raw[:16], raw[16:] cipher = AES.new(key, AES.MODE_CBC, iv) plain = unpad(cipher.decrypt(ct), AES.block_size)

IV 和密文必须一起 base64 编码,否则无法分离。

记住:AES 本身不解决密钥管理、完整性校验(别漏 HMAC)、密钥轮换这些事。如果数据要长期存储或跨服务共享,光靠 AES.MODE_CBC + 手动 padding 是不够稳健的。