SHA256哈希值有多长?

315

我将在密码加盐后运行SHA256算法,但是在设置MySQL数据库时不知道该将VARCHAR字段长度设为多少。有什么好的长度建议吗?


17
在任何人决定跟随这篇文章的建议并使用 SHA-* 来进行密码哈希之前,请务必先阅读此文。请注意不要改变原意,尽可能使内容通俗易懂,但不提供解释或其他信息。 - c00000fd
4
除非您正在对密码使用SHA-256(而您不应该这样做),否则哈希值长度为256位,或64个十六进制字符,或43个字母数字字符,或32个字节。 - caw
@c00000fd:我不确定这个链接是否特别相关。OP明确想要使用“密码+盐”。例如,如果盐是16个随机字符,那么SHA-256的速度快并且字典攻击是不可能的。请参考GNU文档中的crypt示例代码。SHA-x对于口令短语来说是可以的,只要你知道你在做什么。 - EML
@EML:这个链接是正确的,SHA-256 的速度确实很重要。无论你知不知道自己在做什么,SHA-x 都不适合用于口令。 - President James K. Polk
@PresidentJamesK.Polk:做些计算。如果要运行SHA-xn次来破解明文密码,那么添加一个16字节的盐意味着必须运行n * 256^16次。即使密码本身非常简单-比如只有一个可打印字符-那么SHA-x也必须运行3 * 10^40次才能测试所有可能性。如果您拥有一个以每秒11十亿个SHA-256操作运行的GPU设置,则需要3 * 10^30秒。这比宇宙的年龄多得多。因此,SHA-x“快速”的事实是完全无关紧要的。 - EML
显示剩余4条评论
5个回答

447

SHA256是一个256位长的哈希函数。根据其名称,它返回一个十六进制表示。

由于sha256返回一个十六进制表示,因此4位就足以编码每个字符(与ASCII相比需要8位),所以256位将代表64个十六进制字符,因此您需要一个varchar(64), 甚至一个char(64), 因为长度始终相同,不会变化。

以下是演示:

$hash = hash('sha256', 'hello, world!');
var_dump($hash);

我会为您提供:

$ php temp.php
string(64) "68e656b251e67e8358bef8483ab0d51c6619f3e7a1a9f0e75838d41ff368f728"

即一个包含 64 个字符的字符串。

7
我们可以使用 char(64) 作为主键,或者 binary(32) 是否更适合?(access_token) - frankish
4
如果你认为将来可能需要屏蔽某个用户,那么我建议在前面使用 varchar(65) 作为一个前导的 !……仅仅是说一下。 - Manatax
144
还是只需添加一个“已屏蔽”列吗? - Stijn de Witt
6
为了让每个密码都有不同的盐值,您需要将其存储在散列值旁边。您可以使用额外的字段或在散列值之前/之后添加它,因此您将需要超过64个字符。 - Patrick Cornelissen
4
您可以使用以下选择语句进行测试:SELECT length(to_base64(unhex(sha2('say hello to my little friend',256)))),无论原始字符串的长度如何,结果始终为44。 - DrAhmedJava
显示剩余5条评论

85

SHA256的256位编码选项:

  1. Base64:每个字符6个比特= CHAR(44)(包括填充字符)
  2. 十六进制:每个字符4个比特 = CHAR(64)
  3. 二进制:每个字节8个比特= BINARY(32)

35
Base64每4个字符表示3个字节,所以尽管32字节可以编码为43个字符,但实际上需要44个字符。作为最后一个字符,会添加一个额外的“=”。 - Wilco
5
好的,=``=符号可以被添加和去除。 - Rick James

36

我喜欢使用BINARY(32),因为这是优化的方法!

你可以在其中放置从(00至FF)的32个十六进制数字。

因此,选择BINARY(32)!


13
+1 - 我喜欢优化...给其他人使用时...与MySQL一起使用...你可以使用 UPDATE...SET hash_column=UNHEX(sha256HexString)。然后,当检索时,你可以使用 SELECT HEX(hash_column) AS hash_column - Kevin Nelson
一个相关的MySQL文档:https://dev.mysql.com/doc/refman/8.0/en/encryption-functions.html - Buttle Butkus

26

你为什么要将它定义为VARCHAR类型?它的长度是不变的。它始终是64个字符,可以通过在在线SHA-256计算器中输入任何内容来确定。


1
char(64) 是一个有效的 MySQL 语句吗? - Tony Stark
32
不是陈述句,但它是一种有效的列类型。 - Mark Byers
11
与char不同,varchar只有在使用时才分配空间,而不会预先分配允许的字符总数的空间,无论是否有数据填充。请注意保持原意并尽可能简洁易懂。 - Xenland

8

长度将固定为64个字符,因此请使用char(64)


2
请使用 字符集 ascii - Rick James
或者BINARY(64),因为你在这里并不真正处理文本。 - theking2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接