开发手册 欢迎您!
软件开发者资料库

Python PyCrypto(PyCryptodome) ASE实现对文件加密和解密方法

本文主要分享一下Python3中通过PyCrypto(PyCryptodome)调用ASE实现对文件的加密和解密方法代码。

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 PyCryptodome

3、完整代码

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('