当前位置: 首页 > 工具软件 > PyCryptodome > 使用案例 >

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

谭伟
2023-12-01

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

outfile.write(iv)

pos = 0

while pos < filesize:

chunk = infile.read(chunksize)

pos += len(chunk)

if pos == filesize:

chunk = pad(chunk, AES.block_size)

outfile.write(encryptor.encrypt(chunk))

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

iv = infile.read(16)

encryptor = AES.new(key, AES.MODE_CBC, iv)

with open(out_filename, 'wb') as outfile:

encrypted_filesize = os.path.getsize(in_filename)

pos = 8 + 16 # the filesize and IV.

while pos < encrypted_filesize:

chunk = infile.read(chunksize)

pos += len(chunk)

chunk = encryptor.decrypt(chunk)

if pos == encrypted_filesize:

chunk = unpad(chunk, AES.block_size)

outfile.write(chunk)

注意:上面代码与Python2/Python3兼容,它应该可以与PyCryptodome或PyCrypto一起使用。

但是,虽然本文介绍的是PyCrypto,还是建议您更新到PyCryptodome。PyCryptodome是PyCrypto的一个分支,它公开了相同的API(因此您不需要过多地更改代码),还提供了一些额外的特性:填充函数、经过身份验证的加密算法、KDFs等。另一方面,PyCrypto不再被维护,而且一些版本还存在基于堆的缓冲区溢出漏洞。

安装PyCryptodome使用下面命令:pip install PyCryptodome

3、完整代码import os, random, struct

from Crypto.Cipher import AES

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]

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

outfile.write(iv)

pos = 0

while pos < filesize:

chunk = infile.read(chunksize)

pos += len(chunk)

if pos == filesize:

chunk = pad(chunk, AES.block_size)

outfile.write(encryptor.encrypt(chunk))

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

iv = infile.read(16)

encryptor = AES.new(key, AES.MODE_CBC, iv)

with open(out_filename, 'wb') as outfile:

encrypted_filesize = os.path.getsize(in_filename)

pos = 8 + 16 # the filesize and IV.

while pos < encrypted_filesize:

chunk = infile.read(chunksize)

pos += len(chunk)

chunk = encryptor.decrypt(chunk)

if pos == encrypted_filesize:

chunk = unpad(chunk, AES.block_size)

outfile.write(chunk)

#测试代码

if __name__=='__main__':

encrypt_file("keyskeyskeyskeys".encode('utf-8'),"/root/myfile")

decrypt_file("keyskeyskeyskeys".encode('utf-8'),"/root/myfile.enc")

 类似资料: