这是 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))任何帮助都将不胜感激。
发布于 2018-07-16 13:22:28
那么,让我们看一看IV可能包含的内容:
IV = ''
for i in range(16):
IV += chr(random.randint(0, 0xFF))让我们看看来自range(0, 0xff)的字符消耗了多少字节:
>>> [len(chr(i).encode()) for i in range(0, 0xff)]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]这就是问题的根源:假设每个字符都有一个字节长,但事实并非如此。
您可以使用以下代码生成N个字节的随机IV:
import os
N = 16
IV = os.urandom(N)代码中的另一个问题是,您正在以'rb'模式打开所有文件,这表示“读取二进制文件”,但试图将str的实例(如IV )写入其中。这是行不通的,因为在这种模式下,您只允许读写bytes,而不是str。在我计算IV的解决方案中,这个问题完全消失了。
发布于 2018-07-16 13:22:45
您尚未将IV字符串转换为字节字符串。在Python3中,str不是字节字符串,而是字符串。str是从字符如何表示为字节的概念中抽象出来的。
您需要将IV变量(也许还有其他变量,我还没有检查)转换为bytes的实例。在Python 3中编写字节串也要容易一些。
random_byte_list = [random.randrange(256) for _ in range(16)]
IV = bytes(random_byte_list)https://stackoverflow.com/questions/51362459
复制相似问题