使用 pycrypto 进行对称加密

Python 的内置加密功能目前仅限于散列。加密需要第二方模块,如 pycrypto 。例如,它提供 AES 算法 ,该算法被认为是对称加密的现有技术。以下代码将使用密码加密给定的消息:

import hashlib
import math
import os

from Crypto.Cipher import AES

IV_SIZE = 16    # 128 bit, fixed for the AES algorithm
KEY_SIZE = 32   # 256 bit meaning AES-256, can also be 128 or 192 bits
SALT_SIZE = 16  # This size is arbitrary

cleartext = b'Lorem ipsum'
password = b'highly secure encryption password'
salt = os.urandom(SALT_SIZE)
derived = hashlib.pbkdf2_hmac('sha256', password, salt, 100000,
                              dklen=IV_SIZE + KEY_SIZE)
iv = derived[0:IV_SIZE]
key = derived[IV_SIZE:]

encrypted = salt + AES.new(key, AES.MODE_CFB, iv).encrypt(cleartext)

AES 算法采用三个参数:加密密钥,初始化向量(IV)和要加密的实际消息。如果你有一个随机生成的 AES 密钥,那么你可以直接使用该密钥,只生成一个随机初始化向量。密码短语不具有正确的大小,但也不建议直接使用密码短语,因为它不是真正随机的,因此具有相对较小的熵。相反,我们使用 PBKDF2 算法内置实现从密码生成 128 位初始化向量和 256 位加密密钥。

注意随机盐对于每个加密的消息具有不同的初始化向量和密钥很重要。这尤其可以确保两条相同的消息不会产生相同的加密文本,但它也可以防止攻击者重复使用另一个密码加密的消息猜测一个密码的工作。该盐必须与加密消息一起存储,以便导出相同的初始化向量和用于解密的密钥。

以下代码将再次解密我们的消息:

salt = encrypted[0:SALT_SIZE]
derived = hashlib.pbkdf2_hmac('sha256', password, salt, 100000,
                              dklen=IV_SIZE + KEY_SIZE)
iv = derived[0:IV_SIZE]
key = derived[IV_SIZE:]
cleartext = AES.new(key, AES.MODE_CFB, iv).decrypt(encrypted[SALT_SIZE:])