PostgreSQL pgcrypto加解密算法
目录
普通哈希函数
- digest()
digest(data text, type text) 返回 bytea
digest(data bytea, type text) 返回 bytea
计算一个给定data
的一个二进制哈希值。type
是要使用的算法。标准算法是md5
、sha1
、sha224
、sha256
、sha384
和sha512
。如果使用 OpenSSL 编译了pgcrypto
,如表 F.20中所述,有更多算法可用。
如果你想摘要成为一个十六进制字符串,可以在结果上使用encode()
。例如:
CREATE OR REPLACE FUNCTION sha1(bytea) returns text AS $$
SELECT encode(digest($1, 'sha1'), 'hex')
$$ LANGUAGE SQL STRICT IMMUTABLE;
- hmac()
hmac(data text, key text, type text) 返回 bytea
hmac(data bytea, key text, type text) 返回 bytea
为带有密钥key的data计算哈希过的 MAC。type与digest()中相同。
这与digest()相似,但是该哈希只能在知晓密钥的情况下被重新计算出来。这阻止了某人修改数据且还想更改哈希以匹配之的企图。
如果该密钥大于哈希块的尺寸,它将先被哈希然后把结果用作密钥。
口令哈希函数
函数crypt()和gen_salt()是特别设计用来做口令哈希的。crypt()完成哈希,而gen_salt()负责为前者准备算法参数。
crypt()中的算法在以下方面不同于通常的 MD5 或 SHA1 哈希算法:
- 它们很慢。由于数据量很小,这是增加蛮力口令破解难度的唯一方法。
- 它们使用一个随机值(称为salt),这样具有相同口令的用户将得到不同的密文口令。这也是针对逆转算法的一种额外保护。
- 它们会在结果中包括算法类型,这样用不同算法哈希的口令能共存。
- 其中一些是自适应的 — 这意味着当计算机变得更快时,你可以调整该算法变得更慢,而不会产生与现有口令的不兼容。
表 F.17列出了crypt()
函数所支持的算法。
- crypt()
crypt(password text, salt text) 返回 text
计算password的一个 crypt(3) 风格的哈希。在存储一个新口令时,你需要使用gen_salt()产生一个新的salt值。要检查一个口令,把存储的哈希值作为salt,并且测试结果是否匹配存储的值。
设置一个新口令的例子:
UPDATE ... SET pswhash = crypt('new password', gen_salt('md5'));
认证的例子:
SELECT (pswhash = crypt('entered password', pswhash)) AS pswmatch FROM ... ;
如果输入的口令正确,这会返回true。
- gen_salt()
gen_salt(type text [, iter_count integer ]) 返回 text
产生一个在crypt()
中使用的新随机 salt 字符串。该 salt 字符串也告诉了crypt()
要使用哪种算法。
type
参数指定哈希算法。可接受的类型是:des
、xdes
、md5
以及bf
。
iter_count
参数让用户可以为使用迭代计数的算法指定迭代计数。计数越高,哈希口令花的时间更长并且因而需要更多时间去攻破它。不过使用太高的计数会导致计算一个哈希的时间高达数年 — 这并不使用。如果iter_count
参数被忽略,将使用默认的迭代计数。允许的iter_count
值与算法相关,如表 F.18所示。
对xdes
算法还有额外的限制:迭代计数必须是一个奇数。
要选取一个合适的迭代计数,考虑最初的 DES 加密被设计成在当时的硬件上每秒钟完成 4 次哈希。低于每秒 4 次哈希的速度很可能会损害可用性。而超过每秒 100 次哈希又可能太快了。
表 F.19给出了不同哈希算法的相对慢度的综述。该表展示了在假设口令只含有小写字母或者大小写字母及数字的情况下,在一个 8 字符口令中尝试所有字符组合所需要的时间。在crypt-bf
项中,在一个斜线之后的数字是gen_salt
的iter_count
参数
注意:
使用的机器是一台 Intel Mobile Core i3。
crypt-des和crypt-md5算法的数字是取自 John the Ripper v1.6.38 -test输出。
md5 hash的数字来自于 mdcrack 1.2。
sha1的数字来自于 lcrack-20031130-beta.
crypt-bf的数字是采用一个在 1000 个 8 字符口令上循环的简单程序采集到的。用那种方法我能展示不同迭代次数的速度。供参考:john-test对于crypt-bf/5显示 13506 次循环/秒(结果中的微小差异符合pgcrypto中的crypt-bf实现与 John the Ripper 中的一致这一情况)。
注意:
使用的机器是一台 Intel Mobile Core i3。
crypt-des和crypt-md5算法的数字是取自 John the Ripper v1.6.38 -test输出。
md5 hash的数字来自于 mdcrack 1.2。
sha1的数字来自于 lcrack-20031130-beta.
crypt-bf的数字是采用一个在 1000 个 8 字符口令上循环的简单程序采集到的。用那种方法我能展示不同迭代次数的速度。供参考:john-test对于crypt-bf/5显示 13506 次循环/秒(结果中的微小差异符合pgcrypto中的crypt-bf实现与 John the Ripper 中的一致这一情况)。
未完待续。。。
更多交流加群: PostgreSQL内核开发群 876673220