Vibe.d Password Verification
Matthew
monkeytonk115 at gmail.com
Sat Feb 8 20:09:46 UTC 2025
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.
```D
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
```json
{
"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`.
```sh
> 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.
```sh
> ./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/
More information about the Digitalmars-d-learn
mailing list