PostgreSQL中的PBKDF2函数

时间:2017-11-07 15:56:17

标签: postgresql pbkdf2

不是问题,但我想我会分享......

无法在本地找到它,并且基于'net上找到的PHP code,我想出了PostgreSQL的这个PBKDF2函数。享受。

create or replace function PBKDF2 
  (salt bytea, pw text, count integer, desired_length integer, algorithm text)
  returns bytea
  immutable
  language plpgsql
as $$
declare 
  hash_length integer;
  block_count integer;
  output bytea;
  the_last bytea;
  xorsum bytea;
  i_as_int32 bytea;
  i integer;
  j integer;
  k integer;
begin
  algorithm := lower(algorithm);
  case algorithm
  when 'md5' then
    hash_length := 16;
  when 'sha1' then
    hash_length = 20;
  when 'sha256' then
    hash_length = 32;
  when 'sha512' then
    hash_length = 64;
  else
    raise exception 'Unknown algorithm "%"', algorithm;
  end case;

  block_count := ceil(desired_length::real / hash_length::real);

  for i in 1 .. block_count loop    
    i_as_int32 := E'\\000\\000\\000'::bytea || chr(i)::bytea;
    i_as_int32 := substring(i_as_int32, length(i_as_int32) - 3);

    the_last := salt::bytea || i_as_int32;

    xorsum := HMAC(the_last, pw::bytea, algorithm);
    the_last := xorsum;

    for j in 2 .. count loop
      the_last := HMAC(the_last, pw::bytea, algorithm);

      --
      -- xor the two
      --
      for k in 1 .. length(xorsum) loop
        xorsum := set_byte(xorsum, k - 1, get_byte(xorsum, k - 1) # get_byte(the_last, k - 1));
      end loop;
    end loop;

    if output is null then
      output := xorsum;
    else
      output := output || xorsum;
    end if;
  end loop;

  return substring(output from 1 for desired_length);
end $$;

我已经针对其他实现进行了测试而没有偏差,但请务必自行测试。

欢迎改进和建议。

0 个答案:

没有答案