from Crypto.Cipher import AES
def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024):
""" Encrypts a file using AES (CBC mode) with the
given key.
key:
The encryption key - a string that must be
either 16, 24 or 32 bytes long. Longer keys
are more secure.
in_filename:
Name of the input file
out_filename:
If None, '<in_filename>.enc' will be used.
chunksize:
Sets the size of the chunk which the function
uses to read and encrypt the file. Larger chunk
sizes can be faster for some files and machines.
chunksize must be divisible by 16.
"""
if not out_filename:
out_filename = in_filename + '.enc'
iv = ''.join(chr(random.randint(0, 0xFF)) for i in range(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('<Q', filesize))
outfile.write(iv)
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
elif len(chunk) % 16 != 0:
chunk += ' ' * (16 - len(chunk) % 16)
outfile.write(encryptor.encrypt(chunk))
这是我加密文件的方式,但是如果你在同一个文件上运行两次或更多文件,它会不加问地加密它,我想添加某种if检查它是否已经加密通过AES?这可能吗?
答案 0 :(得分:4)
最常用的解决方案是在加密文件的开头写一些“魔术”字符串,然后加密内容。如果在读取文件时找到该字符串,则拒绝进一步加密。对于解密,我们非常认为这是我们加密的文件,但是否则会被忽略。
想象一下,你正在使用“MyCrYpT”作为魔法(尽管你使用 并不重要,只要它是相当独特的。
magic = "MyCrYpT"
# writing the encrypted file
with open(out_filename, 'wb') as outfile:
outfile.write(magic) # write the identifier.
outfile.write(struct.pack('<Q', filesize)) # file size
outfile.write(iv)
# et cetera
现在,在阅读文件时,我们读取所有数据,然后检查它是否是我们的。然后我们放弃魔法并处理剩下的魔法。
with open(in_filename, 'rb') as infile:
data = infile.read()
if data[:len(magic)] != magic:
raise ValueError('Not an encrypted file')
filedata = data[len(magic):]
# Proces the file data
答案 1 :(得分:0)
除非你有一些可以检测到的神奇标题(例如,在Linux上,LUKS加密磁盘映像有一个标题块用于添加功能,但DM-Crypt没有),否则很难检测到输入字符串是否加密。