Reputation: 84540
I'm trying to find a bcrypt
implementation I can use in Delphi. About the only useful thing that Googling brings me is this download page, containing translated headers for a winapi unit called bcrypt.h
. But when I look at the functionality it provides, bcrypt.h
doesn't appear to actually contain any way to use the Blowfish algorithm to hash passwords!
I've found a few bcrypt implementations in C that I could build a DLL from and link to, except they seem to all require *nix or be GCC-specific, so that won't work either!
This is sorta driving me up the wall. I'd think that it would be easy to find an implementation, but that doesn't seem to be the case at all. Does anyone know where I could get one?
Upvotes: 17
Views: 8089
Reputation: 256581
Okay, so i wrote it.
Usage:
hash: string;
hash := TBCrypt.HashPassword('mypassword01');
returns something like:
$2a$10$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm
The useful thing about this (OpenBSD) style password hash is:
2a
= bcrypt)Ro0CUfOqk6cXEKf3dyaM7O
)10
).To check a password is correct:
isValidPassword: Boolean;
isValidPassword := TBCrypt.CheckPassword('mypassword1', hash);
BCrypt uses a cost factor, which determines how many iterations the key setup will go though. The higher the cost, the more expensive it is to compute the hash. The constant BCRYPT_COST
contains the default cost:
const
BCRYPT_COST = 10; //cost determintes the number of rounds. 10 = 2^10 rounds (1024)
In this case a cost of 10
means the key will be expanded and salted 210
=1,024 rounds. This is the commonly used cost factor at this point in time (early 21st century).
It is also interesting to note that, for no known reason, OpenBSD hashed passwords are converted to a Base-64 variant that is different from the Base64 used by everyone else on the planet. So TBCrypt
contains a custom base-64 encoder and decoder.
It's also useful to note that the hash algorithm version 2a
is used to mean:
So that is why the HashPassword
and CheckPassword
functions take a WideString
(aka UnicodeString
), and internally convert them to UTF-8. If you're running this on a version of Delphi where UnicodeString
is a reserved word, then simply define out:
type
UnicodeString = WideString;
i, as David Heffernan knows, don't own Delphi XE 2. i added the UnicodeString
alias, but didn't include compilers.inc
and define away UnicodeString
(since i don't know the define name, nor could i test it). What do you want from free code?
The code comprises of two units:
Where on the intertubes can i put some code where it can live in perpetuity?
Update 1/1/2015: It was placed onto GitHub some time ago: BCrypt for Delphi.
Bonus 4/16/2015: There is now Scrypt for Delphi
Upvotes: 24