1、PyCryptodome的padding方法
pad和unpad函数是从Crypto.Util复制的。填充并修改为只使用PKCS7填充。注意,当使用PKCS7填充时,填充最后一个块是很重要的,即使它的大小是块大小的倍数,否则您将无法正确地解填充。
try:
from Crypto.Util.Padding import pad, unpad
except ImportError:
from Crypto.Util.py3compat import bchr, bord
def pad(data_to_pad, block_size):
padding_len = block_size-len(data_to_pad)%block_size
padding = bchr(padding_len)*padding_len
return data_to_pad + padding
def unpad(padded_data, block_size):
pdata_len = len(padded_data)
if pdata_len % block_size:
raise ValueError("Input data is not padded")
padding_len = bord(padded_data[-1])
if padding_len<1 or padding_len>min(block_size, pdata_len):
raise ValueError("Padding is incorrect.")
if padded_data[-padding_len:]!=bchr(padding_len)*padding_len:
raise ValueError("PKCS#7 padding is incorrect.")
return padded_data[:-padding_len]
2、文件加密和解密方法
1)加密方法代码
def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024): if not out_filename: out_filename = in_filename + '.enc' iv = os.urandom(16) encryptor = AES.new(key, AES.MODE_CBC, iv) filesize = os.path.getsize(in_filename) with open(in_filename, 'rb') as infile: with open(out_filename, 'wb') as outfile: outfile.write(struct.pack('2)解密方法代码
def decrypt_file(key, in_filename, out_filename=None, chunksize=64*1024): if not out_filename: out_filename = in_filename + '.dec' with open(in_filename, 'rb') as infile: filesize = struct.unpack('注意:上面代码与Python2/Python3兼容,它应该可以与PyCryptodome或PyCrypto一起使用。
但是,虽然本文介绍的是PyCrypto,还是建议您更新到PyCryptodome。PyCryptodome是PyCrypto的一个分支,它公开了相同的API(因此您不需要过多地更改代码),还提供了一些额外的特性:填充函数、经过身份验证的加密算法、KDFs等。另一方面,PyCrypto不再被维护,而且一些版本还存在基于堆的缓冲区溢出漏洞。
安装PyCryptodome使用下面命令:
pip install PyCryptodome3、完整代码
import os, random, structfrom Crypto.Cipher import AEStry: from Crypto.Util.Padding import pad, unpadexcept ImportError: from Crypto.Util.py3compat import bchr, bord def pad(data_to_pad, block_size): padding_len = block_size-len(data_to_pad)%block_size padding = bchr(padding_len)*padding_len return data_to_pad + padding def unpad(padded_data, block_size): pdata_len = len(padded_data) if pdata_len % block_size: raise ValueError("Input data is not padded") padding_len = bord(padded_data[-1]) if padding_len<1 or padding_len>min(block_size, pdata_len): raise ValueError("Padding is incorrect.") if padded_data[-padding_len:]!=bchr(padding_len)*padding_len: raise ValueError("PKCS#7 padding is incorrect.") return padded_data[:-padding_len]def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024): if not out_filename: out_filename = in_filename + '.enc' iv = os.urandom(16) encryptor = AES.new(key, AES.MODE_CBC, iv) filesize = os.path.getsize(in_filename) with open(in_filename, 'rb') as infile: with open(out_filename, 'wb') as outfile: outfile.write(struct.pack('