如何解决文件加密后打不开的问题:使用 base64 编码和 AES 加密
在文件加密函数中,我们使用异或运算加密每个字节,这样可能会导致一些特定的字节被加密后变成控制字符或不可见字符,从而导致加密后的文件无法打开。为了解决这个问题,我们可以使用 base64 编码来加密文件,这样可以保证加密后的文件是可见字符序列,同时也保证了解密后的数据正确性。修改后的加密和解密函数如下所示:
import base64
# 此函数用于实际执行文件加密操作
def encrypt_file(input_file_path, output_file_path, key):
try:
with open(input_file_path, 'rb') as input_file:
with open(output_file_path, 'wb') as output_file:
data = input_file.read()
# 使用 base64 编码加密数据
encrypted_data = base64.b64encode(data)
# 将密钥转换为字节数组
key_bytes = str(key).encode('utf-8')
# 使用 AES 加密算法加密数据
cipher = AES.new(key_bytes, AES.MODE_EAX)
ciphertext, tag = cipher.encrypt_and_digest(encrypted_data)
# 将加密后的数据和加密参数写入输出文件中
[ output_file.write(x) for x in (cipher.nonce, tag, ciphertext) ]
# 根据输出文件的扩展名选择保存方式
file_extension = os.path.splitext(output_file_path)[1]
if file_extension == '.docx':
# 如果是.docx 文件,则使用 python-docx 库保存
doc = docx.Document(output_file_path)
doc.save(output_file_path)
elif file_extension == '.xlsx':
# 如果是.xlsx 文件,则使用 openpyxl 库保存
wb = openpyxl.load_workbook(output_file_path)
wb.save(output_file_path)
return True
except Exception as e:
messagebox.showerror('Error', str(e))
return False
# 此函数用于实际执行文件解密操作
def decrypt_file(input_file_path, output_file_path, key):
try:
with open(input_file_path, 'rb') as input_file:
with open(output_file_path, 'wb') as output_file:
# 读取加密参数和加密后的数据
nonce, tag, ciphertext = [ input_file.read(x) for x in (16, 16, -1) ]
# 将密钥转换为字节数组
key_bytes = str(key).encode('utf-8')
# 使用 AES 解密算法解密数据
cipher = AES.new(key_bytes, AES.MODE_EAX, nonce=nonce)
decrypted_data = cipher.decrypt_and_verify(ciphertext, tag)
# 使用 base64 解码解密后的数据
decrypted_data = base64.b64decode(decrypted_data)
# 将解密后的数据写入输出文件中
output_file.write(decrypted_data)
# 根据输出文件的扩展名选择保存方式
file_extension = os.path.splitext(output_file_path)[1]
if file_extension == '.docx':
# 如果是.docx 文件,则使用 python-docx 库保存
doc = docx.Document(output_file_path)
doc.save(output_file_path)
elif file_extension == '.xlsx':
# 如果是.xlsx 文件,则使用 openpyxl 库保存
wb = openpyxl.load_workbook(output_file_path)
wb.save(output_file_path)
return True
except Exception as e:
messagebox.showerror('Error', str(e))
return False
需要注意的是,使用 base64 编码加密数据会导致加密后的文件大小变大,因此需要留意文件是否会超过限制大小。另外,解密时也需要先读取加密参数和加密后的数据,再进行解密操作。
原文地址: https://www.cveoy.top/t/topic/oRSN 著作权归作者所有。请勿转载和采集!