Thread overview
Vibe.d Password Verification
Feb 05
seany
Feb 05
Sergey
Feb 08
Matthew
Feb 11
Kagamin
February 05

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.

February 05

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

February 05
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



February 05

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.

February 06

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

February 08

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/

February 11

uint32_t is from stdint.h, which id is import core.stdc.stdint;