首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python 2加密程序在python 3中转换并运行时会返回错误

Python 2加密程序在python 3中转换并运行时会返回错误
EN

Stack Overflow用户
提问于 2018-07-16 13:01:28
回答 2查看 476关注 0票数 0

这是 this 问题的延续。请不要将这个问题标记为重复,因为它有一个不同的错误,我需要修复.

用于链接的TL;DR:

所以我问我的加密程序在python中出现了Unicode错误,有人告诉我只需在utf-8中对密码进行编码就可以了。

现在我有了第二个问题,它说IV不是16个字节,所以我在IV之后放入print(len(IV))进行检查,在运行3次测试之后,它只返回16次,位于打印字符的中间,结束字符大于16 (例如: 37、35、28等)。

我如何解决这个问题,以便IV总是返回16个字节?

完全错误:

代码语言:javascript
复制
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

代码:

代码语言:javascript
复制
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))

任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-07-16 13:22:28

那么,让我们看一看IV可能包含的内容:

代码语言:javascript
复制
IV = ''

for i in range(16):
    IV += chr(random.randint(0, 0xFF))

让我们看看来自range(0, 0xff)的字符消耗了多少字节:

代码语言:javascript
复制
>>> [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:

代码语言:javascript
复制
import os

N = 16
IV = os.urandom(N)

代码中的另一个问题是,您正在以'rb'模式打开所有文件,这表示“读取二进制文件”,但试图将str的实例(如IV )写入其中。这是行不通的,因为在这种模式下,您只允许读写bytes,而不是str。在我计算IV的解决方案中,这个问题完全消失了。

票数 3
EN

Stack Overflow用户

发布于 2018-07-16 13:22:45

您尚未将IV字符串转换为字节字符串。在Python3中,str不是字节字符串,而是字符串。str是从字符如何表示为字节的概念中抽象出来的。

您需要将IV变量(也许还有其他变量,我还没有检查)转换为bytes的实例。在Python 3中编写字节串也要容易一些。

代码语言:javascript
复制
random_byte_list = [random.randrange(256) for _ in range(16)]
IV = bytes(random_byte_list)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51362459

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档