PBKDF2
synxroform opened this issue · comments
Can you help me with PBKDF2 function ? Can't find it in your library. It will be helpful for web frameworks.
This implements a 1-round PBKDF2 with SHA256. Something to start with anyway.
(from my https://github.com/BioTurboNick/Scrypt.jl)
const HASH_LENGTH = 256 ÷ 8
function pbkdf2_sha256_1(key, salt::Vector{UInt8}, derivedkeylength)
blockcount = cld(derivedkeylength, HASH_LENGTH)
lastblockbytes = derivedkeylength - (blockcount - 1) * HASH_LENGTH
salt = [salt; zeros(UInt8, 4)]
salttail = view(salt, length(salt) - 3:length(salt))
derivedkey = Matrix{UInt8}(undef, HASH_LENGTH, blockcount)
for i ∈ 1:blockcount
salttail[:] = reinterpret(UInt8, [UInt32(i)]) |> reverse
derivedkey[:, i] = digest("sha256", key, salt)
end
derivedkey = reshape(derivedkey, blockcount * HASH_LENGTH)[1:derivedkeylength]
return derivedkey
end
Hi @BioTurboNick I'm trying to implement pbkdf2 using hmac sha512 with multiple iterations. I looked at your script and start from it. Also looking at the documentation to implement it.
At the moment this is the code I got
using SHA
function pbkdf2(key::AbstractString, salt::String, iterations::Int, dklen::Int)::Vector{UInt8}
hlen = trunc(Int, dklen / 8)
@assert dklen % hlen === 0
nblocks = convert(Int, round(dklen / hlen))
derived_key = Matrix{UInt8}(undef, hlen, nblocks)
salt_bytes = Vector{UInt8}(salt)
for i in 1:nblocks
derived_key[:, i] = pbkdf2_block(key, salt_bytes, iterations, i)
end
derived_key = reshape(derived_key, nblocks * hlen)[1:dklen]
return derived_key
end
function pbkdf2_block(key::AbstractString, salt::Vector{UInt8}, iterations::Int, i::Int)::Vector{UInt8}
salt = [salt; zeros(UInt8, 4)]
salt_tail = view(salt, length(salt) - 3:length(salt))
salt_tail[:] = reinterpret(UInt8, [UInt32(i)]) |> reverse
U1 = hmac_sha2_512(Vector{UInt8}(key), salt)
Un = U1
for i in 2:iterations
Un = Un .⊻ hmac_sha2_512(Vector{UInt8}(key), Un)
end
return Un
end
By the way this doesn't seems to return the right result. I'm not a cryptography expert and this is the only thread I've found about PBKDF2 in Julia. Do you have any suggestion?
I'm afraid this isn't really my area. However, I find a good place to start is to try copying a known-good function in another language as close as possible (e.g. don't use broadcasting etc.) so it provides the correct result, and then apply Julia-style to it. Also inspect each step by executing in the REPL to make sure it's doing exactly what you expect it to. At least that'll show you where the problem starts. That's how I would approach solving your issue.