【问题标题】:Why SHA256 hashes finish with " = "?为什么 SHA256 哈希以“=”结尾?
【发布时间】:2015-06-06 07:10:23
【问题描述】:

我制作了一个 Web 服务,它在成功验证后返回一个安全令牌。

但是,在调试时,我注意到 Web 服务返回的每个哈希都以“=”结尾,例如:

"tINH0JxmryvB6pRkEii1iBYP7FRedDqIEs0Ppbw83oc="
"INv7q72C1HvIixY1qmt5tNASFBEc0PnXRSb780Y5aeI="
"QkM8Kog8TtCczysDmKu6ZOjwwYlcR2biiUzxkb3uBio="
"6eNuCU6RBkwKMmVV6Mhm0Q0ehJ8Qo5SqcGm3LIl62uQ="
"dAPKN8aHl5tgKpmx9vNoYvXfAdF+76G4S+L+ep+TzU="
"O5qQNLEjmmgCIB0TOsNOPCHiquq8ALbHHLcWvWhMuI="
"N9ERYp+i7yhEblAjaKaS3qf9uvMja0odC7ERYllHCI="
"wsBTpxyNLVLbJEbMttFdSfOwv6W9rXba4GGodVVxgo="
"sr+nF83THUjYcjzRVQbnDFUQVTkuZOZYe3D3bmF1D8="
"9EosvgyYOG5a136S54HVmmebwiBJJ8a3qGVWD878j5k="
"8ORZmAXZ4dlWeaMOsyxAFphwKh9SeimwBzf8eYqTis="
"gVepn2Up5rjVplJUvDHtgIeaBL+X6TPzm2j9O2JTDFI="

为什么会有这样的行为?

【问题讨论】:

  • SHA 密钥是一个整数,这里这可能是密钥的base64 编码。由于密钥是 256 位宽或 32 字节,因此它将被编码为大约 4/3 * 32 ~= 43 个字符。
  • 为什么它们只有 44 个字符长?你在什么基础上编码它们?
  • @pzp 答案就在上面。
  • 这很奇怪;当我在 base64 中编码我的 SHA256 输出时,它们总是 64 个字符长。
  • @pzp 然后要么不是 sha256,要么不是 base64:例如,sha512 密钥的宽度为 64 字节,但在 base64 中大约有 85 个字符。 sha384 密钥确实会在 base64 中编码为 64 个字符。查看here 了解 SHA 的变体

标签: base64 behavior sha256


【解决方案1】:

这是因为您看不到哈希的原始字节,而是看到 Base64 编码。

Base64 编码将 3 个字节的块转换为 4 个字符的块。如果字节数可被 3 整除,则此方法效果很好。如果不是,则使用填充字符,因此生成的字符数仍可被 4 整除。

所以:

(no of bytes)%3 = 0  => no padding needed
(no of bytes)%3 = 1  => pad with ==
(no of bytes)%3 = 2  => pad with =

SHA256 哈希是 256 位,即 32 个字节。因此,前 30 个字节为 40 个字符,后 2 个字节为 3 个字符,填充始终为一个 =

【讨论】:

  • 我当然同意这个答案,但我无法解释为什么问题中的字符串长度不一样。也许是OP的错误?
【解决方案2】:

这些字符串使用base64编码,=字符用作填充,使base64字符串的最后一个块包含四个字符。


以下 Ruby 代码可用于获取 base64 解码字符串:

require 'base64'

s = "tINH0JxmryvB6pRkEii1iBYP7FRedDqIEs0Ppbw83oc="
puts Base64.decode64(s).bytes.map{|e| '%02x' % e}.join

输出:b48347d09c66af2bc1ea94641228b588160fec545e743a8812cd0fa5bc3cde87

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-28
    • 2019-12-08
    • 2012-02-09
    • 1970-01-01
    • 2015-10-25
    • 2014-01-14
    • 1970-01-01
    • 2011-03-02
    相关资源
    最近更新 更多