【发布时间】:2018-07-16 13:01:28
【问题描述】:
这是this 问题的延续。请不要将此问题标记为重复问题,因为它有另一个我需要修复的错误。
TL;链接的DR:
所以我在询问我的加密程序在 python 中的 Unicode 错误,有人告诉我只需将密码编码为 utf-8 即可。
现在我有第二个问题,它说 IV 不是 16 字节,所以我通过在 IV 之后放置 print(len(IV)) 来检查这一点,并且在运行 3 次测试后它只返回 16 一次,在中间打印字符,且结束字符大于 16(例如:37、35、28 等)。
我该如何解决这个问题,以便 IV 始终返回 16 个字节?
完全错误:
Traceback (most recent call last):
File "/home/pi/Desktop/Projects/FyleCript/Dev Files/encryption.py", line 77, in <module>
encrypt(SHA256.new(password.encode('utf-8')).digest(), str(Tfiles))
File "/home/pi/Desktop/Projects/FyleCript/Dev Files/encryption.py", line 17, in encrypt
encryptor = AES.new(key, AES.MODE_CBC, IV)
File "/usr/lib/python3/dist-packages/Crypto/Cipher/AES.py", line 94, in new
return AESCipher(key, *args, **kwargs)
File "/usr/lib/python3/dist-packages/Crypto/Cipher/AES.py", line 59, in __init__
blockalgo.BlockAlgo.__init__(self, _AES, key, *args, **kwargs)
File "/usr/lib/python3/dist-packages/Crypto/Cipher/blockalgo.py", line 141, in __init__
self._cipher = factory.new(key, *args, **kwargs)
ValueError: IV must be 16 bytes long
代码:
def encrypt(key, filename):
chunksize = 64 * 1024
outFile = os.path.join(os.path.dirname(filename), "(encrypted)"+os.path.basename(filename))
filesize = str(os.path.getsize(filename)).zfill(16)
IV = ''
for i in range(16):
IV += chr(random.randint(0, 0xFF))
encryptor = AES.new(key, AES.MODE_CBC, IV)
with open(filename, "rb") as infile:
with open(outFile, "wb") as outfile:
outfile.write(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))
def decrypt(key, filename):
outFile = os.path.join(os.path.dirname(filename), os.path.basename(filename[11:]))
chunksize = 64 * 1024
with open(filename, "rb") as infile:
filesize = infile.read(16)
IV = infile.read(16)
decryptor = AES.new(key, AES.MODE_CBC, IV)
with open(outFile, "wb") as outfile:
while True:
chunk = infile.read(chunksize)
if len(chunk) == 0:
break
outfile.write(decryptor.decrypt(chunk))
outfile.truncate(int(filesize))
任何帮助将不胜感激。
【问题讨论】:
-
我注意到的第一件事:
if choice == "E" or 'e'永远是真的。而是做if choice in ( "E", 'e') -
我们不需要查看您的整个程序,只需查看重现问题所需的最少数量。有很多可以删减。
-
加密时不要使用
os.random(),而是使用Crypto.Random()。检查this answer以了解如何正确执行此操作,它还显示了 Python 2.x 和 3.x 之间的差异。
标签: python python-3.x encryption pycrypto