【问题标题】:How to base64 encode a SHA256 hex character string如何对 SHA256 十六进制字符串进行 base64 编码
【发布时间】:2022-02-09 13:40:52
【问题描述】:

您好,我需要帮助来获得一个 base64 编码的列,我得到的是一个 sha256 散列列,我想得到 44 个字符,但是当我在 python 中尝试这个时

[base64.b64encode(x.encode('utf-8')).decode() for x in xxx['yyy']]

它返回 88 个字符,有人可以帮忙吗?基本上我想用Python实现下面图片中显示的步骤,谢谢!

【问题讨论】:

  • 为什么你“想得到 44 个字符”?请提供一个具体的例子,展示你投入的东西,你得到的东西,并解释你期望得到的东西。
  • 我对你想要做什么感到困惑。当我运行您的代码时,列表中的每个项目都有 4 个字符,列表中的项目数取决于xxx['yyy'] 中有多少个字符。我看不到应该在哪里看到 44 或 88 个字符。
  • @Grismar,我不熟悉编码。所以我有一个 64 个字符的 sha256 散列电子邮件列,我在网上使用 base64 编码工具,我得到 44 个字符,但我有整个列要编码,试图找出 Python 代码来做到这一点..
  • @hostingutitities.com 很抱歉造成混乱。 xxx 是假设一个表名,yyy 是一个 64 个字符的 sha256 散列电子邮件列,但我需要使用 base64 编码将其编码为 44 个字符..
  • Base64永远不会使字符串变小,它总是会变大。

标签: python base64 encode sha256


【解决方案1】:

第一张图片中的步骤由几个子步骤组成:

  • 输入了一个文本,但这只是 UTF-8 编码的字符表示
  • sha256 散列应用于该字节字符串
  • 生成的摘要字节序列以其十六进制表示形式呈现

所以:

from hashlib import sha256

s = 'user@example.com'

h = sha256()
h.update(s.encode('utf-8'))  # specifying encoding, optional as this is the default
hex_string = h.digest().hex()
print(hex_string)

第二张图片似乎表明它再次将十六进制表示作为文本,并且 base64 对其进行编码 - 但实际上它采用十六进制字符串表示的字节字符串并对其进行编码。

所以,从十六进制字符串开始:

  • 将十六进制解码为字节(重构摘要字节)
  • 使用 base64 将字节编码为 ascii 字节字符串
  • 将生成的字节字符串解码为用于打印的字符
from base64 import b64encode

digest_again = bytes.fromhex(hex_string)
b64bytes = b64encode(digest_again)
# no real need to specify 'ascii', the relevant code points overlap with UTF-8:
result = b64bytes.decode('ascii')
print(result)

放在一起:

from hashlib import sha256
from base64 import b64encode

s = 'user@example.com'

h = sha256()
h.update(s.encode())
print(h.digest().hex())

b64bytes = b64encode(h.digest())
print(b64bytes.decode())

输出:

b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514
tMmiiTI7IaAcPpQPFQ65uMVCWH8av9jw4cwf/F5HVRQ=

为什么您的代码不起作用:

base64.b64encode('user@example.com'.encode('utf-8')).decode()  # superfluous utf-8

这个:

  • 使用 UTF-8 将字符“user@example.com”编码为字节
  • 使用 base64 对该字节字符串进行编码
  • 将生成的字节串解码为字符串

它不会在任何地方应用 SHA256 哈希,也不会创建十六进制表示,如果您期望的话。最终结果不匹配,因为它是原始文本 UTF-8 编码的 base64 编码的文本表示,而不是其 SHA256 哈希的摘要。

或者我误解了,你已经有了十六进制编码,但是你把它作为一个字符串:

x = 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514'
base64.b64encode(x.encode()).decode()

这确实会产生 88 个字符的 base64 编码,因为您不是在对字节进行编码,而是在对十六进制表示进行编码。那应该是这样的:

x = 'b4c9a289323b21a01c3e940f150eb9b8c542587f1abfd8f0e1cc1ffc5e475514'
base64.b64encode(bytes.fromhex(x)).decode()

...也许这就是您正在寻找的答案。

【讨论】:

  • OMG,非常感谢,我尝试了 base64.b64encode(bytes.fromhex(x)).decode(),它立即生效!!!
  • 很高兴为您提供帮助,请随时单击答案旁边的复选标记,表示它已解决您的问题,您的问题将不再显示为未回答。
【解决方案2】:

This answer 在 Cryptography Stack Exchange 上讨论了为什么会得到 64 个字符。基本上,由于历史原因,哈希通常是十六进制编码的,即使这会产生 64 个字符,而 base64 编码的哈希只有 44 个字符。但是,如果您需要对它进行 base64 编码,则有一种方法可以做到。下面会给你一个base64编码的哈希

from base64 import b64encode
from hashlib import sha256

email = 'user@example.com'
email_as_bytes = email.encode('utf-8')
hash_as_bytes = b64encode(sha256(email_as_bytes).digest())
hash = hash_as_bytes.decode('utf-8')

由于 b64encode 和 sha256 都对字节进行操作,我们可以将它们链接在一起,并且生成的代码不会太糟糕。

【讨论】:

  • 请注意,OP 得到的是 88 个字符而不是 44 个字符,而不是 64 个(由于编码了十六进制编码,而不是编码原始字节序列,这确实是长度的两倍)
猜你喜欢
  • 2016-07-19
  • 1970-01-01
  • 1970-01-01
  • 2013-06-10
  • 1970-01-01
  • 2020-11-11
  • 1970-01-01
  • 1970-01-01
  • 2019-03-20
相关资源
最近更新 更多