Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PBKDF2 function in PostgreSQL

How can the PBKDF2 function be done in PostgreSQL? There does not appear to be a native implementation.

like image 272
ktekinay Avatar asked Nov 19 '22 05:11

ktekinay


1 Answers

Moved Answer out of Question to adhere to Stack Overflow guidelines. See original revision of post.

Original post (Revision link)

Not able to find it natively, and based on PHP code found on the 'net, I came up with this PBKDF2 function for PostgreSQL. Enjoy.

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 $$;

I've tested against other implementations without deviation, but be sure to test it yourself.

like image 88
General Grievance Avatar answered May 22 '23 01:05

General Grievance