www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Vibe.d Password Verification

reply seany <seany uni-bonn.de> writes:
Is there any built in passowrd verification for Vibe.d? Such as 
bcrypt.verifypassword(password , hash)?

I looked at this library: https://code.dlang.org/packages/passwd
This is causing linking error ( ld: error: unable to find library 
-lbsd) - yes i am on FreeBSD with my hoster. I can't change it.

I also looked at this one: https://code.dlang.org/packages/crypto
I can't find a verify password method in it.

Any help would be appreciated. My password is being sent as 
string over a secure https connection. The hash is stored as 
another string.

Thank you.
Feb 05
next sibling parent Sergey <kornburn yandex.ru> writes:
On Wednesday, 5 February 2025 at 15:16:10 UTC, seany wrote:
 Any help would be appreciated. My password is being sent as 
 string over a secure https connection. The hash is stored as 
 another string.
There are also these 2: https://code.dlang.org/packages/dauth https://code.dlang.org/packages/arsd-official%3Aargon2
Feb 05
prev sibling next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, February 5, 2025 8:16:10 AM MST seany via Digitalmars-d-learn
wrote:
 Is there any built in passowrd verification for Vibe.d? Such as
 bcrypt.verifypassword(password , hash)?

 I looked at this library: https://code.dlang.org/packages/passwd
 This is causing linking error ( ld: error: unable to find library
 -lbsd) - yes i am on FreeBSD with my hoster. I can't change it.

 I also looked at this one: https://code.dlang.org/packages/crypto
 I can't find a verify password method in it.

 Any help would be appreciated. My password is being sent as
 string over a secure https connection. The hash is stored as
 another string.

 Thank you.
Not having tackled this problem myself, my suggestion would be to simply write bindings for bcrypt. As long as it's in C, you shouldn't need many functions, so writing the bindings should be dead simple. Or you could try importC rather than manually writing the bindings, but I'm guessing that you'll only need to worry about a couple of functions. Also as a general rule, you probably should avoid libraries written in D which provide any crypto stuff unless they're simply bindings for C stuff, because without a security expert verifying them, it's _really_ easy to have security issues even if they're otherwise great libraries, and you're unlikely to find a library with that kind of vetting on code.dlang.org. - Jonathan M Davis
Feb 05
prev sibling next sibling parent Adam Wilson <flyboynw gmail.com> writes:
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)?

 I looked at this library: https://code.dlang.org/packages/passwd
 This is causing linking error ( ld: error: unable to find 
 library -lbsd) - yes i am on FreeBSD with my hoster. I can't 
 change it.

 I also looked at this one: 
 https://code.dlang.org/packages/crypto
 I can't find a verify password method in it.

 Any help would be appreciated. My password is being sent as 
 string over a secure https connection. The hash is stored as 
 another string.

 Thank you.
There is one crypto package that includes a secure password hashing/verification implementation and has had it's implementation vetted. SecureD: https://code.dlang.org/packages/secured The algorithm you are looking for is `securePassword/verifyPassword` methods in `secured.kdf`. By default this will use SCrypt. PBKDF2 is available for backwards compatibility but is not recommended for use in new projects.
Feb 05
prev sibling next sibling parent Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
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)?

 I looked at this library: https://code.dlang.org/packages/passwd
 This is causing linking error ( ld: error: unable to find 
 library -lbsd) - yes i am on FreeBSD with my hoster. I can't 
 change it.

 I also looked at this one: 
 https://code.dlang.org/packages/crypto
 I can't find a verify password method in it.

 Any help would be appreciated. My password is being sent as 
 string over a secure https connection. The hash is stored as 
 another string.

 Thank you.
Long ago, I played around with this. I used dauth, which is already mentioned. https://github.com/aferust/simplerestvibed/blob/master/source/app.d You may also be interested in my d port of its dangerous Python package, in which you can use timed and/or untimed web tokens. This is not heavily tested in "dangerous" environments, though :) https://pypi.org/project/itsdangerous/ https://github.com/aferust/itsdangerous-d
Feb 06
prev sibling parent reply Matthew <monkeytonk115 gmail.com> writes:
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/
Feb 08
parent Kagamin <spam here.lot> writes:
uint32_t is from stdint.h, which id is `import core.stdc.stdint;`
Feb 11