为什么在解码为ascii之前必须先进行十六进制处理?

时间:2018-07-18 14:21:53

标签: python decode digital-signature pycryptodome

因此,我一直在尝试使用python(特别是pycryptodome)来更好地了解加密,并且遇到了一个有趣的问题,试图将字节字符串解码为ascii。请参见下面的代码:

from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
message = b'Something secret'

random_gen = Crypto.Random.new().read
print("Type of random_gen: {}".format(type(random_gen)))
private_key = RSA.generate(1024, random_gen) # private key
public_key = private_key.publickey() # public key

signer = PKCS1_v1_5.new(private_key) # signer which uses private key
verifier = PKCS1_v1_5.new(public_key) # verifier which uses public key

h = SHA.new(message) # hash of message
print("Hash: {}".format(h.hexdigest()))

signature = signer.sign(h) # sign hashed version of message
print("Signature type = {}".format(type(signature)))
print("Signature: {}".format(binascii.hexlify(signature).decode('ascii')))

为什么在代码的最后一行中,我必须首先hexlify()签名为<class 'bytes'>类型的签名,然后才能将其解码为ascii以便阅读签名?为什么会这样:

print("Signature: {}".format(signature.decode('ascii')))

我收到以下错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0x88 in position 2: ordinal not in range(128)

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

signature是字节序列:每个元素都是0到255之间的整数,如果您尝试直接以ascii对其进行解码,则大于127的值将引发异常。

binascii.hexlify从其输入返回一个新的字节序列:对于输入中的每个字节,在输出中将返回两个字节,它们是与输入字节的十六进制表示相对应的ascii字符代码。因此,输出的每个字节代表一个'0''9'之间或'a''f'之间的ASCII字符。例如,输入字节128产生两个字符"80",因此,两个字节5648(这是字符'8'和{ {1}}。

因此'0'以二进制输入的ascii形式生成十六进制表示形式。在binascii.hexlify之后应用的decode('ascii')不会更改内容,但是会产生binascii.hexlify类型的对象。

在python 3.5及更高版本中,您可以简单地使用str对象的hex方法来获取包含其十六进制表示形式的bytes对象:

str