错误“UnicodeDecodeError:‘utf-8’编解码器在位置1无法解码字节0xbf:使用pycryptodome解密后开始字节“解码字节”

时间:2023-01-04 20:30:06

My problem is that when I use pycryptodome for decrypting a string in Python 3.6 with the following code:

我的问题是,当我使用pycryptodome对Python 3.6中的字符串进行解密时,有以下代码:

from Crypto.Cipher import AES
from Crypto import Random

key = "133BBB3212332231"
key_bytestring = key.encode("utf-8")
iv = Random.new().read(AES.block_size)
cipher = AES.new(key_bytestring, AES.MODE_CFB, iv)
encrypted_string = 'ý\x82iq\x193\x1aÙË\x04Û£¥\x8dbBOW}Vû\x01\x86zÕ¼Ó)áôO\x14'
encrypted_bytes = encrypted_string.encode("utf-8")
decrypted_bytes = cipher.decrypt(encrypted_bytes)
decrypted_string = decrypted_bytes.decode("utf-8")
print(decrypted_string )

Python throws this error: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbf in position 1: invalid start byte

Python抛出这个错误:UnicodeDecodeError: 'utf-8' codec不能解码位置1中的字节0xbf:无效的开始字节。

In this line:

在这条线:

decrypted_string = decrypted_bytes.decode("utf-8")

I'm updating some code from Python 2.7, and pycrypto has changed to pycryptdodome. In python 2.7 this works like a charm with pycrypto(I've invented the key so the string is not decrypted well but Python don't throw any error):

我正在更新Python 2.7中的一些代码,pycrypto已经更改为pycryptdodome。在python 2.7中,这就像pycrypto的魅力(我发明了密钥,所以字符串不会被很好地解密,但是python不会抛出任何错误):

from Crypto.Cipher import AES
from Crypto import Random

key = "133BBB3212332231"
iv = Random.new().read(AES.block_size)
cipher = AES.new(key, AES.MODE_CFB, iv)
encrypted_string = 'ý\x82iq\x193\x1aÙË\x04Û£¥\x8dbBOW}Vû\x01\x86zÕ¼Ó)áôO\x14'
decrypted_string = cipher.decrypt(encrypted_string)
print(decrypted_string)

How can I fix this? I'm quite desperate, since I've been trying it for a long time and I did't come to anything. Thank you in advance!

我该怎么解决这个问题呢?我很绝望,因为我已经尝试了很长一段时间,我什么都没做。提前谢谢你!

2 个解决方案

#1


1  

First you should know how Python 3 treats strings differently than in Python 2.

首先,您应该知道Python 3对待字符串的方式与Python 2不同。

In Python 2, "" is a byte array, but in Python 3 it's a unicode string. Both cipher.encrypt and cipher.decrypt expect byte arrays.

在Python 2中,“”是一个字节数组,但是在Python 3中,它是一个unicode字符串。这两个密码。加密和加密。解密期望字节数组。

So even though in both pieces of code, the type of your parameter is fine. Your problem in Python 3 is with calling str.encode. It's pretty easy to see that it indeed caused a change by looking at the string length:

因此,即使在这两段代码中,参数的类型也没有问题。您在Python 3中的问题是调用string .encode。很容易看出它确实通过观察弦的长度引起了变化:

>>> len(encrypted_string)
10
>>> len(encrypted_string.encode('utf-8'))
14

The solution:

解决方案:

First of all notice that in Python 2:

首先,请注意在Python 2中:

>>> "¨vóîÄdX|@9" == '\xc2\xa8v\xc3\xb3\xc3\xae\xc3\x84dX|@9'
True

In Python 3, you need to mark your string with the binary prefix (b""), your new definition should use: encrypted_bytes = b'\xc2\xa8v\xc3\xb3\xc3\xae\xc3\x84dX|@9'

在Python 3中,您需要使用二进制前缀(b“”)标记字符串,您的新定义应该使用:encrypted_bytes = b'\xc2\xa8v\xc3\ xc3\xb3\xc3\ xc3\ xc3\ xc3\ xc3\ xc3\ xc3\ xc3\ \xc3\ xc3\ xc3\ \xc3\ xc3\ xc3\ xc3\ x3\ x3\ x3\ x3\ bb4dx | \ bb4dx | |@9' @9' @ ' ' ' ' ' ' ' ' ' '

Thus your solution should be:

因此,你的解决办法应该是:

from Crypto.Cipher import AES
from Crypto import Random

key = "18945BKJVO9W834G"
iv = Random.new().read(AES.block_size)
cipher = AES.new(key, AES.MODE_CFB, iv)
encrypted_bytes = b'\xc2\xa8v\xc3\xb3\xc3\xae\xc3\x84dX|@9'
decrypted_bytes = cipher.decrypt(encrypted_bytes)
print(decrypted_bytes)

#2


0  

like this :

是这样的:

from Crypto.Cipher import AES
from Crypto import Random

key = "18945BKJVO9W834G"
key_bytestring = key
iv = Random.new().read(AES.block_size)
cipher = AES.new(key_bytestring, AES.MODE_CFB, iv)
encrypted_string = "¨vóîÄdX|@9"
encrypted_bytes = encrypted_string 
decrypted_bytes = cipher.decrypt(encrypted_bytes)
decrypted_string = decrypted_bytes
print(repr(decrypted_string))

Short description : Byte and String got same pattern, does not require any correction. Consider how the system is perceived if you do any encoding operation.Cryptographic logic is a byte-based function, which is not very important to which encoding system you are using. If the input/output or output/input is important to you why do you change the encoding setting of the characters? Computers cannot read and write!

短描述:字节和字符串得到相同的模式,不需要任何修正。如果进行任何编码操作,请考虑系统是如何感知的。密码逻辑是一种基于字节的函数,对于使用哪个编码系统来说并不重要。如果输入/输出或输出/输入对您很重要,为什么要更改字符的编码设置?电脑不能读写!

#1


1  

First you should know how Python 3 treats strings differently than in Python 2.

首先,您应该知道Python 3对待字符串的方式与Python 2不同。

In Python 2, "" is a byte array, but in Python 3 it's a unicode string. Both cipher.encrypt and cipher.decrypt expect byte arrays.

在Python 2中,“”是一个字节数组,但是在Python 3中,它是一个unicode字符串。这两个密码。加密和加密。解密期望字节数组。

So even though in both pieces of code, the type of your parameter is fine. Your problem in Python 3 is with calling str.encode. It's pretty easy to see that it indeed caused a change by looking at the string length:

因此,即使在这两段代码中,参数的类型也没有问题。您在Python 3中的问题是调用string .encode。很容易看出它确实通过观察弦的长度引起了变化:

>>> len(encrypted_string)
10
>>> len(encrypted_string.encode('utf-8'))
14

The solution:

解决方案:

First of all notice that in Python 2:

首先,请注意在Python 2中:

>>> "¨vóîÄdX|@9" == '\xc2\xa8v\xc3\xb3\xc3\xae\xc3\x84dX|@9'
True

In Python 3, you need to mark your string with the binary prefix (b""), your new definition should use: encrypted_bytes = b'\xc2\xa8v\xc3\xb3\xc3\xae\xc3\x84dX|@9'

在Python 3中,您需要使用二进制前缀(b“”)标记字符串,您的新定义应该使用:encrypted_bytes = b'\xc2\xa8v\xc3\ xc3\xb3\xc3\ xc3\ xc3\ xc3\ xc3\ xc3\ xc3\ xc3\ \xc3\ xc3\ xc3\ \xc3\ xc3\ xc3\ xc3\ x3\ x3\ x3\ x3\ bb4dx | \ bb4dx | |@9' @9' @ ' ' ' ' ' ' ' ' ' '

Thus your solution should be:

因此,你的解决办法应该是:

from Crypto.Cipher import AES
from Crypto import Random

key = "18945BKJVO9W834G"
iv = Random.new().read(AES.block_size)
cipher = AES.new(key, AES.MODE_CFB, iv)
encrypted_bytes = b'\xc2\xa8v\xc3\xb3\xc3\xae\xc3\x84dX|@9'
decrypted_bytes = cipher.decrypt(encrypted_bytes)
print(decrypted_bytes)

#2


0  

like this :

是这样的:

from Crypto.Cipher import AES
from Crypto import Random

key = "18945BKJVO9W834G"
key_bytestring = key
iv = Random.new().read(AES.block_size)
cipher = AES.new(key_bytestring, AES.MODE_CFB, iv)
encrypted_string = "¨vóîÄdX|@9"
encrypted_bytes = encrypted_string 
decrypted_bytes = cipher.decrypt(encrypted_bytes)
decrypted_string = decrypted_bytes
print(repr(decrypted_string))

Short description : Byte and String got same pattern, does not require any correction. Consider how the system is perceived if you do any encoding operation.Cryptographic logic is a byte-based function, which is not very important to which encoding system you are using. If the input/output or output/input is important to you why do you change the encoding setting of the characters? Computers cannot read and write!

短描述:字节和字符串得到相同的模式,不需要任何修正。如果进行任何编码操作,请考虑系统是如何感知的。密码逻辑是一种基于字节的函数,对于使用哪个编码系统来说并不重要。如果输入/输出或输出/输入对您很重要,为什么要更改字符的编码设置?电脑不能读写!