Is there a recommended or built in routine for pbkdf2 in Erlang?

Please Is there a recommended or built in routine for pbkdf2 in Erlang?

  
# Example
  saltBytes = :base64.decode("pIvg1BwcNoLXt0xtEv9rZw==")
  calcHashBytes = pbkdf2("1111", saltBytes)
  :base64.encode(calcHashBytes)
  # expected: "dEXM43iRxE+ZscV56wxMaW+JBmgCvOjo7iqj4wgPckM="
  
  defp pbkdf2(password, salt), do: pbkdf2(password, salt, :sha256, 20000, 32, 1, [], 0)

  defp pbkdf2(_password, _salt, _digest, _rounds, dklen, _block_index, acc, length)
       when length >= dklen do
    key = acc |> Enum.reverse() |> IO.iodata_to_binary()
    <<bin::binary-size(dklen), _::binary>> = key
    bin
  end

  defp pbkdf2(password, salt, digest, rounds, dklen, block_index, acc, length) do
    initial = :crypto.hmac(digest, password, <<salt::binary, block_index::integer-size(32)>>)
    block = iterate(password, digest, rounds - 1, initial, initial)

    pbkdf2(
      password,
      salt,
      digest,
      rounds,
      dklen,
      block_index + 1,
      [block | acc],
      byte_size(block) + length
    )
  end

  defp iterate(_password, _digest, 0, _prev, acc), do: acc

  defp iterate(password, digest, round, prev, acc) do
    next = :crypto.hmac(digest, password, prev)
    iterate(password, digest, round - 1, next, :crypto.exor(next, acc))
  end

This is what i currently use, it works, but is there an alternative?

Only implkementation I’m aware off is pbkdf2_elixir.

3 Likes
pbkdf2(Type, MacLength, Count, Length, Pass, Salt) ->
    pubkey_pbe:pbdkdf2(Pass, Salt, Count, Length, fun pbdkdf2_hmac/4, Type, MacLength).

pbdkdf2_hmac(Type, Key, Data, MacLength) ->
    crypto:macN(hmac, Type, Key, Data, MacLength).

pbdkdf2(sha, 20, 4096, 20, “password”, “salt”).