在 MySQL 中存储 SHA1 哈希值
-
03-07-2019 - |
题
当我想将 SHA1 哈希结果存储在 MySQL 数据库中时,出现了一个简单的问题:
应该多长时间 VARCHAR 我存储哈希结果的字段是什么?
解决方案
我会将 VARCHAR
用于可变长度数据,但不能使用固定长度数据。由于SHA-1值总是 160位长, VARCHAR
只会浪费固定长度字段长度的附加字节。
而且我也不会存储值 SHA1
正在返回。因为它每个字符仅使用4位,因此需要160/4 = 40个字符。但是如果你每个字符使用8位,那么你只需要一个160/8 = 20个字符的长字段。
所以我建议你使用 BINARY(20 )
和 UNHEX
功能将 SHA1
值转换为二进制。
我比较了 BINARY(20)
和 CHAR(40)
的存储要求。
CREATE TABLE `binary` (
`id` int unsigned auto_increment primary key,
`password` binary(20) not null
);
CREATE TABLE `char` (
`id` int unsigned auto_increment primary key,
`password` char(40) not null
);
有数百万条记录 binary(20)
需要44.56M,而 char(40)
需要64.57M。
InnoDB
引擎。
其他提示
SHA1哈希长度为40个字符!
以下是哈希算法及其所需位大小的列表:
- MD5 = 128 位哈希值。
- SHA1 = 160 位哈希值。
- SHA224 = 224 位哈希值。
- SHA256 = 256 位哈希值。
- SHA384 = 384 位哈希值。
- SHA512 = 512 位哈希值。
使用 require CHAR(n) 创建了一个示例表:
CREATE TABLE tbl_PasswordDataType
(
ID INTEGER
,MD5_128_bit CHAR(32)
,SHA_160_bit CHAR(40)
,SHA_224_bit CHAR(56)
,SHA_256_bit CHAR(64)
,SHA_384_bit CHAR(96)
,SHA_512_bit CHAR(128)
);
INSERT INTO tbl_PasswordDataType
VALUES
(
1
,MD5('SamplePass_WithAddedSalt')
,SHA1('SamplePass_WithAddedSalt')
,SHA2('SamplePass_WithAddedSalt',224)
,SHA2('SamplePass_WithAddedSalt',256)
,SHA2('SamplePass_WithAddedSalt',384)
,SHA2('SamplePass_WithAddedSalt',512)
);
sha1的输出大小为160位。这是160/8 == 20个字符(如果你使用8位字符)或160/16 = 10(如果你使用16位字符)。
因此长度介于10个16位字符和40个十六进制数字之间。
在任何情况下,决定您要存储的格式,并根据该格式将字段设置为固定大小。 这样你就不会浪费任何空间。
如果您不总是为用户存储哈希值(即验证帐户/忘记登录URL),您可能仍希望使用VARCHAR。一旦用户验证/更改了他们的登录信息,他们就不应该使用哈希并且没有理由。您可以创建一个单独的表来存储临时哈希 - >可以删除的用户关联,但我认为大多数人都不愿意这样做。
如果你需要sha1列的索引,我建议CHAR(40)出于性能原因。 在我的情况下,sha1列是电子邮件确认令牌,因此在登录页面上,查询仅使用令牌输入。 在这种情况下,我认为带有INDEX的CHAR(40)是最佳选择:)
如果您想采用此方法,请记住留下$ raw_output = false。