使用 base64 编码,为什么我得到错误的答案?

Encode using base64, why am I getting wrong answer?

我正在尝试对 websocket 进行身份验证。 在文档的示例中,如果我的客户随机数是:

nonce = 0xf08c98caf1fd82e8cea9825dbff04fd0 

然后我应该编码它使用base64得到:

target = "8IyYyvH9gujOqYJdv/BP0A==".

我不确定我做错了什么,但我得到以下信息:

client_nonce = 0xf08c98caf1fd82e8cea9825dbff04fd0
str_client_nonce = str(client_nonce) 
encoded = b64encode(bytes(str_client_nonce, 'utf-8'))
print(encoded)

>> b'MzE5NzQ0NzM5NTUzODE1NjMyMTAxNjk0MjM1NzExODU0NjI4ODE2'

首先,0xf08c98caf1fd82e8cea9825dbff04fd0 是 Python 中的一个数字(例如 0x10 是 16 的另一种写法)。但是数字并不是你实际拥有的,你有字节列表的十六进制表示,也称为十六进制字符串。

要做的事情:

  • 摆脱 0x,使用字符串。
  • 将该字符串解码为字节。
  • 将这些字节编码为 base64。

代码:

import base64

nonce_hex = 'f08c98caf1fd82e8cea9825dbff04fd0'
nonce = bytearray.fromhex(nonce_hex)
base64_nonce = base64.encodebytes(nonce)

# -> b'8IyYyvH9gujOqYJdv/BP0A==\n'

实际随机数总是字节。 represent/store/transport 这些字节使用了不同的方法。使用十六进制字符串是一种常见的方式。使用 base64 是另一回事。十六进制字符串和 base64 都用于相同的目的:以字符串形式存储任意字节以便于处理。 Base64 碰巧比十六进制字符串需要更少 space,这就是为什么它通常是首选的原因。上面的代码只是将字节的一种字符串表示形式转换为另一种。

您必须将 nonce 直接转换为 bytes。不是 string 表示

通过

b = int2bytes(nonce)
b'\xf0\x8c\x98\xca\xf1\xfd\x82\xe8\xce\xa9\x82]\xbf\xf0O\xd0'
base64.b64encode(b)
b'8IyYyvH9gujOqYJdv/BP0A=='

str(client_nonce) 给你 '0xf08...' 而你可能将其直接转换为字节:

client_nonce.to_bytes(2, byteorder='big')