-1

我正在学习使用pgcrypto中的crypt()函数来加密我的密码并将它们存储到用户表中。

但是,如果我们将现有密码作为第二个参数传递,我不明白 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; $$

在上面的示例中,如果我执行并存储变量的值。

I get : "$2a$06$.lub5s4Eqz4.epcg5zW4Ke" for generated_salt "$2a$06$.lub5s4Eqz4.epcg5zW4KervErzw//uARn8F2gchj2wM11ok.MJLK" for hashResult "$2a$06$.lub5s4Eqz4.epcg5zW4KervErzw//uARn8F2gchj2wM11ok.MJLK" for authenticationPassword

为什么authenticationPassword与hashResult相同,我希望它用 hashResult 作为盐再次对其进行哈希处理。

它如何判断它是否必须识别和计算相同的密码或基于盐生成新的哈希?

PS:我了解如何使用该功能来存储/检索密码,但我不明白它是如何做到的。

谢谢您的帮助,

4

2 回答 2

1

我终于明白发生了什么,crypt 函数只使用前 29 个字符(作为盐传递)来生成 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

于 2021-10-19T16:10:23.547 回答
1

只要您使用相同的盐,生成的哈希对于每个密码将始终是相同的。这就是验证密码时发生的情况。

诀窍在于,当一个新密码被散列(而不是在验证它时)时,引擎会为其选择一个全新的随机盐,因此几乎不可能从散列结果中猜测它。

于 2021-10-18T21:01:16.843 回答