Reputation: 103
Is there a "simple" function in Delphi (using 10.3 Professional) that allows me to verify a password with a hash code generated in PHP using password_hash()
? A function which does the same as PHP's password_verify($password, $hash)
?
Example using PHP:
$hash = password_hash('thisismyaccesscode', PASSWORD_DEFAULT);
// $hash == '$2y$10$21qire0Qwz/gj6HEej3tf.skdiZzeB.rgFdg7qD.5rAhE/AFg.U8q'
Now I'm looking for a Delphi function, that tells me, if the password entered into my program can be verified against this hash.
Background: I have a list of user records for my web server. Using a web service I can retrieve a user's password hash from that server. I know it is generated using the PHP function password_hash()
. I want to enable my users to log in to my Delphi program using the access code from the web site. Therefore I get the password hash from the web server and want to verify it locally in my Delphi program instead of uploading the password to the server and checking with PHP.
Upvotes: 2
Views: 510
Reputation: 643
The algorithms used by the PHP function password_hash()
return different hashes for the same string, because their calculations depends on the used salt and the cost defined by the developer and also the server hardwares (the cost must be high enough so as the function will calculate in the desired time depending on the hardware capacities). So the algorithm must run with the same salt and parameters on the same device (if you optimize your hardware then you have to tune the cost to get the same efficiency, and set a migration process) in order to return the same hash.
In this case, the verification against the hash must occur on the server-side, and you have to send passwords as plain text in requests to the server where you implement a web service to verify passwords. You will have to use HTTPS and work on securing the transportations.
If your server is developed in PHP, you can use the function password_verify()
for verifying against hashes generated by password_hash()
.
But if your server is developed in Delphi, then there is no ready-to-use verification function. You have to use the Delphi port for the algorithm you used, then you implement a function for verifying the passwords (wrapping the hashing algorithm and string verification with the stored hash).
Upvotes: 1
Reputation: 103
I found a BCrypt Delphi library that does what I need.
It's very simple to implement: just add bcrypt.pas
to the uses list.
The class TBCrypt
contains only class functions.
The TBCrypt.CheckPassword
does what I need: input password and hash (I learned, that the hash string, I showed in my question contains the "salt").
My password check is something like:
PWOK := TBCrypt.CheckPassword(KeyedInPwdString, PWHashStringFromWebDB, BooleanDummy);
Upvotes: 2
Reputation: 4269
As you can see in the docs, the string returned by PHP's password_hash
has a format. If your hashes start by $2y
... then you could also understand (reimplement) the PHP password_hash
function as follows (still in PHP):
$salt = base64_encode($random_string_of_22_characters_in_length);
$salt = str_replace('+', '.', $salt);
$hash = crypt('supers3cretpassword', '$2y$10$'.$salt.'$');
That brings you one step further to a Delphi port because crypt()
is an implementation of the standard UNIX DES-based algorithm, for which you will easily find Delphi implementations. A quick google returned TUnixCrypt but I am sure there are others. From its documentation:
... It works exactly as
crypt(key, salt)
Unix command
... which is your missing link. You would only need to parse the salt from within the hash from your server and produce a new hash with that and the user password.
Be aware that the original password could be in a different character encoding to start with, Make sure you encode your password accordingly or non-ascii passwords would fail to verify.
Upvotes: 0