我有一些python代码,我想用它来加密AES 256的各种文件。我使用的是pycrypto模块。它适用于大多数文件(exe,deb,jpg,pdf,txt)但是当涉及到office文件(docx,xlsx,ppt等)时,文件在解密时会被破坏,并且不会打开(也不能修复) LibreOffice的。我使用的是Linux mint,python 2.7.6,pycrypto 2.6.1。我还是一个菜鸟,所以如果你能给我一些你推荐的更正的代码示例,我会很感激。
由于
from Crypto import Random
from Crypto.Cipher import AES
import os
def pad(s):
return s + b"\0" * (AES.block_size - len(s) % AES.block_size)
def encrypt(message, key, key_size=256):
message = pad(message)
iv = Random.new().read(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
return iv + cipher.encrypt(message)
def decrypt(ciphertext, key):
iv = ciphertext[:AES.block_size]
cipher = AES.new(key, AES.MODE_CBC, iv)
plaintext = cipher.decrypt(ciphertext[AES.block_size:])
return plaintext.rstrip(b"\0")
def encrypt_file(file_name, key):
with open(file_name, 'rb') as fo:
plaintext = fo.read()
enc = encrypt(plaintext, key)
with open(file_name + ".enc", 'wb') as fo:
fo.write(enc)
def decrypt_file(file_name, key):
with open(file_name, 'rb') as fo:
ciphertext = fo.read()
dec = decrypt(ciphertext, key)
with open(file_name[:-4], 'wb') as fo:
fo.write(dec)
key = b'\xbf\xc0\x85)\x10nc\x94\x02)j\xdf\xcb\xc4\x94\x9d(\x9e[EX\xc8\xd5\xbfI{\xa2$\x05(\xd5\x18'
encrypt_file('file.docx', key)
答案 0 :(得分:0)
如果需要添加填充以使明文为16字节的倍数,则在写入解密数据之前需要删除额外的字节。这意味着在加密之前,您需要以某种方式包含填充添加的填充字节数。有关一种可能的技术,请参阅PKCS#7。还有许多其他方案。
答案 1 :(得分:0)
问题出在这里
plaintext.rstrip(b"\0")
我已运行该程序,原因是:
这里有一个错误导致原始文件的最后一个字节被丢弃,如果它们碰巧与填充字节具有相同的值!
要解决此问题,我们必须存储加密期间使用的填充字节数,然后在解密期间删除它们。这是我的代码,它适用于我(使用word和excel 2013文件,pdf,jpg测试)。如果还有一些错误,请告诉我。
from Crypto import Random
from Crypto.Cipher import AES
import hashlib
def pad(s):
padding_size = AES.block_size - len(s) % AES.block_size
return s + b"\0" * padding_size, padding_size
def encrypt(message, key, key_size=256):
message, padding_size = pad(message)
iv = Random.new().read(AES.block_size)
cipher = AES.new(key, AES.MODE_CFB, iv)
enc_bytes = iv + cipher.encrypt(message) + bytes([padding_size])
return enc_bytes
def decrypt(ciphertext, key):
iv = ciphertext[:AES.block_size]
cipher = AES.new(key, AES.MODE_CFB, iv)
plaintext = cipher.decrypt(ciphertext[AES.block_size:-1])
padding_size = ciphertext[-1] * (-1)
return plaintext[:padding_size]
def encrypt_file(file_name, key):
with open(file_name, 'rb') as fo:
plaintext = fo.read()
enc = encrypt(plaintext, key)
with open(file_name + ".enc", 'wb') as fo:
fo.write(enc)
def decrypt_file(file_name, key):
with open(file_name, 'rb') as fo:
ciphertext = fo.read()
dec = decrypt(ciphertext, key)
with open('processed_' + file_name[:-4], 'wb') as fo:
fo.write(dec)
key = 'Quan'
hash_object = hashlib.md5(key.encode())
while True:
filename = input('File: ')
en_de = input('En or De?')
if en_de.upper() == 'EN':
encrypt_file(filename, hash_object.hexdigest())
elif en_de.upper() == 'DE':
decrypt_file(filename, hash_object.hexdigest())
else:
print('Did not pick either en or de!')
cont = input('Continue?')
if cont.upper() == 'N':
break