为什么 SHA256 哈希以“=”结尾?

Why SHA256 hashes finish with " = "?

我制作了一个网络服务,在成功验证后returns它是一个安全令牌。

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

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

为什么会有这样的行为?

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


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

require 'base64'

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

输出:b48347d09c66af2bc1ea94641228b588160fec545e743a8812cd0fa5bc3cde87

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

Base64 编码将 3 个字节的块转换为四个字符的块。如果字节数可被 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 个字符,填充将始终为一个 =.