我正在学习使用crypt()函数frompgcrypto将密码加密并存储到用户表中。
然而,我不明白如果我们将现有密码作为第二个参数传递,crypt函数如何可能生成相同的密码。
我想知道它是怎么做到的。
do $$
declare
generated_salt text;
hashResult text;
authenticationPassword text;
begin
-- select the number of actors from the actor table
select public.gen_salt('bf')
into generated_salt;
select public.crypt('password', generated_salt)
into hashResult;
select public.crypt('password', hashResult)
into authenticationPassword;
-- show the number of actors
raise notice 'Generated salt : %', generated_salt;
raise notice 'Hash result : %', hashResult;
raise notice 'authenticationPassword : %', authenticationPassword;
end; $$
在上面的例子中,如果我取一个执行和存储变量的值。
我得到:"2美元06 .lub5s4Eqz4.epcg5zW4Ke"美元;对generated_salt"2美元06 .lub5s4Eqz4.epcg5zW4KervErzw美元//uARn8F2gchj2wM11ok.MJLK"对hashResult"2美元06 .lub5s4Eqz4.epcg5zW4KervErzw美元//uARn8F2gchj2wM11ok.MJLK"对authenticationPassword
为什么authenticationPassword与hashResult相同,我希望它再次哈希它与hashResult作为盐。
它如何判断它是否必须识别和计算相同的密码或基于盐生成新的哈希?
p。S:我知道如何使用存储/检索密码的功能,但我不明白它是如何做到的。
谢谢你的帮助,
只要使用相同的盐,每个密码的结果散列总是相同的。这是验证密码时发生的情况。
诀窍在于,当一个新密码被散列时(而不是在验证它时),引擎会为它选择一个全新的随机盐,因此几乎不可能从散列结果中猜出它。
我终于明白发生了什么,crypt函数只使用前29个字符(作为salt传递)来生成hashOutput,因此即使您在这29个字符后面放置任何东西,结果也将是相同的。例子:
public.crypt('password', '$2a$06$.lub5s4Eqz4.epcg5zW4Ke')
public.crypt('password', '$2a$06$.lub5s4Eqz4.epcg5zW4KervErzw//uARn8F2gchj2wM11ok.MJLK')
public.crypt('password', '$2a$06$.lub5s4Eqz4.epcg5zW4Keyadayadayadayada')
上面3行代码的结果总是$2a$06$. lub5s4eqz4 . epcg5zw4kerverzw//uARn8F2gchj2wM11ok。MJLK真正重要的是前29个字符$2a$06$.lub5s4Eqz4.epcg5zW4Ke以及决定29个字符之后生成什么的密码值:rvErzw//uARn8F2gchj2wM11ok。MJLK
pgcrypto的源代码帮助我理解了下面发生的事情:https://github.com/postgres/postgres/tree/master/contrib/pgcrypto