On Wednesday, 5 February 2025 at 15:16:10 UTC, seany wrote:
> Is there any built in passowrd verification for Vibe.d? Such as bcrypt.verifypassword(password , hash)?
...
Thank you.
I would agree with Jonathan and use a C library. I was just looking for a password solution myself also for a vibe.d project. The OWASP [0] recommends argon2id [1] so I chose that but I'm sure similar applies to bcrypt or scrypt.
I have just written the following test program to check it works (and to check I understand how argon2id works).
I copied and pasted the definitions I needed from /usr/include/argon2.h
. Mark them as extern(C)
. I added two alias definitions because D doesn't have uint32_t
or argon2_type
.
Because they are C functions, they take the password, salt, and hash as pointers and length argument pairs, so for a D string we use password.ptr and password.length.
import std.stdio;
import std.string;
import std.getopt;
alias uint32_t = size_t;
alias argon2_type = uint;
extern(C)
int argon2id_hash_encoded(
const uint32_t t_cost,
const uint32_t m_cost,
const uint32_t parallelism,
const void *pwd,
const size_t pwdlen,
const void *salt,
const size_t saltlen,
const size_t hashlen,
char *encoded,
const size_t encodedlen);
extern(C)
size_t argon2_encodedlen(
uint32_t t_cost,
uint32_t m_cost,
uint32_t parallelism,
uint32_t saltlen,
uint32_t hashlen,
argon2_type type);
enum Argon2_id = 2;
enum HASHLEN = 32;
void main(string[] args)
{
// Bind arguments
string salt;
string password;
uint t_cost;
uint m_cost;
uint p_cost;
char[] encoded_hash;
getopt(args,
"salt", &salt,
"password", &password,
"t", &t_cost,
"m", &m_cost,
"p", &p_cost
);
// calculate and allocate space for the encoded hash string
size_t encodedlen = argon2_encodedlen(t_cost, m_cost, p_cost, salt.length, HASHLEN, Argon2_id);
encoded_hash = new char[encodedlen];
int err = argon2id_hash_encoded(
t_cost, m_cost, p_cost,
password.ptr, password.length,
salt.ptr, salt.length,
HASHLEN,
encoded_hash.ptr, encoded_hash.length
);
writefln("err: %d", err);
writefln("password: %s", password);
writefln("salt: %s", salt);
writefln("hash: %s", encoded_hash);
}
I added argon2 to dub.json libs section
{
"authors": [
"matthew"
],
"copyright": "Copyright © 2025, matthew",
"description": "A minimal D application.",
"license": "proprietary",
"name": "argon_test",
"libs": [
"argon2"
]
}
dub build
and ldd
shows it is dynamically linked to /usr/lib/libargon2.so.1
.
> dub build
Starting Performing "debug" build using /usr/bin/dmd for x86_64.
Building argon_test ~master: building configuration [application]
Linking argon_test
> ldd argon_test
linux-vdso.so.1 (0x00007f393ed43000)
libargon2.so.1 => /usr/lib/libargon2.so.1 (0x00007f393ebd5000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f393eae6000)
libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f393eab8000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f393e8c7000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f393ed45000)
It gives the same encoded hash as the argon2
command line utility so it's probably correct.
> ./argon_test --password 'password' --salt 'wipqozn123456789' -t
4 -m 163840 -p 2
err: 0
password: password
salt: wipqozn123456789
hash: $argon2id$v=19$m=163840,t=4,p=2$d2lwcW96bjEyMzQ1Njc4OQ$So4Z3TuftM1BZcnTpz96MqM/54W9zViOIhdfRwD1ZM4
> printf 'password' | argon2 'wipqozn123456789' -id -t 4 -k 163840 -p 2
Type: Argon2id
Iterations: 4
Memory: 163840 KiB
Parallelism: 2
Hash: 4a8e19dd3b9fb4cd4165c9d3a73f7a32a33fe785bdcd588e22175f4700f564ce
Encoded: $argon2id$v=19$m=163840,t=4,p=2$d2lwcW96bjEyMzQ1Njc4OQ$So4Z3TuftM1BZcnTpz96MqM/54W9zViOIhdfRwD1ZM4
0.350 seconds
Verification ok
Wrap it into a nice D module with proper strings instead of char*
then import it from your other file.
Verification of passwords with hashes and turning this into a vibe.d route is left as an excercise to the reader.
On my machine (arch btw) /usr/include/argon2.h
, /usr/lib/libargon2.so
, and /usr/bin/argon2
are provided by the argon2
[2] package. I can only asume BSD would have an argon2 package.
Hope this helps.
Regards,
Matthew
[0] https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
[1] https://github.com/P-H-C/phc-winner-argon2
[2] https://archlinux.org/packages/extra/x86_64/argon2/