142 lines
4.3 KiB
Markdown
142 lines
4.3 KiB
Markdown
# Free Pascal BCrypt
|
|
|
|
Free Pascal [BCrypt](https://en.wikipedia.org/wiki/Bcrypt "BCrypt") implementation.
|
|
|
|
This started because I wanted something that would be compatible with PHP's $2y$ BCrypt hashing. Ultimately there is no difference between the $2a$ algorithm and the $2y$ algorithm. Just the a, and y. But I didn't want to have a wrapper function that replaced the a with the y.
|
|
|
|
If you try to verify a $2a$ password with PHP it will verify, but if you run the needs rehash function it will always say it needs a rehash. So I moved this to Free Pascal compatible class format.
|
|
|
|
Tested with :
|
|
* Free Pascal
|
|
* 2.6.4
|
|
* Linux
|
|
* Gentoo, 2.2-Current-x64
|
|
* Raspbian
|
|
* 3.0.0
|
|
* Linux
|
|
* Gentoo, 2.2-Current-x64
|
|
* FreeBSD
|
|
* 12.0-CURRENT-x64
|
|
* Windows
|
|
* Windows 10-x64
|
|
* 3.1.1
|
|
* Linux
|
|
* Gentoo, 2.2-Current-x64
|
|
|
|
* PHP
|
|
* 5.5.x
|
|
* 5.5.38-pl0-gentoo
|
|
* 5.6.x
|
|
* 5.6.20-pl0-gentoo
|
|
* 5.6.28-pl0-gentoo
|
|
* 7.0.x
|
|
* 7.0.6_rc1-pl0-gentoo
|
|
* 7.0.13-pl0-gentoo
|
|
* 7.x.x (dev)
|
|
* 7.2.0-dev-x64 (ZTS) 10/31/2016, Gentoo 2.2 Current
|
|
* 7.2.0-dev-x64 (ZTS) 11/02/2016, FreeBSD 12.0-CURRENT
|
|
* HHVM
|
|
* Soon
|
|
|
|
### Usage
|
|
```pascal
|
|
BCrypt.CreateHash(Password);
|
|
BCrypt.CreateHash(Password, HashType);
|
|
BCrypt.CreateHash(Password, HashType, Cost);
|
|
```
|
|
Where
|
|
* Password is the password to be hashed
|
|
* HashType is one of bcPHP, bcBSD, or bcDefault, bcPHP is the default $2y$
|
|
* and Cost is a number between 10 and 30, default is 12.
|
|
```pascal
|
|
var
|
|
BCrypt : TBCryptHash;
|
|
Hash : AnsiString;
|
|
begin
|
|
BCrypt := TBCryptHash.Create;
|
|
Hash := BCrypt.CreateHash('password'); // PHP $2y$ hash with a cost of 12
|
|
// or
|
|
Hash := BCrypt.CreateHash('password', bcBSD); // BSD $2a$ hash with a cost of 12
|
|
// or
|
|
Hash := BCrypt.CreateHash('password', bcPHP, 14); // PHP hash, with a cost of 14
|
|
Writeln(Hash);
|
|
BCrypt.Free;
|
|
end;
|
|
```
|
|
|
|
To verify
|
|
```pascal
|
|
var
|
|
BCrypt : TBCryptHash;
|
|
Hash : AnsiString;
|
|
Verify : Boolean;
|
|
begin
|
|
Hash := '$2y$12$GuC.Gk2YDsp8Yvga.IuSNOWM0fxEIsAEaWC1hqEI14Wa.7Ps3iYFq';
|
|
BCrypt := TBCryptHash.Create;
|
|
Verify := BCrypt.VerifyHash('password', Hash);
|
|
BCrypt.Free;
|
|
end;
|
|
```
|
|
|
|
HashGetInfo - raises EHash exception if the hash is bad, ([too short](https://youtu.be/xT0Qb5ns7_A "too short"), too long);
|
|
```pascal
|
|
var
|
|
BCrypt : TBCryptHash;
|
|
Hash : AnsiString;
|
|
PasswordInfo : RTPasswordInformation;
|
|
begin
|
|
BCrypt := TBCryptHash.Create;
|
|
Hash := '$2y$12$GuC.Gk2YDsp8Yvga.IuSNOWM0fxEIsAEaWC1hqEI14Wa.7Ps3iYFq';
|
|
PasswordInfo := BCrypt.HashGetInfo(Hash);
|
|
with PasswordInfo do
|
|
begin
|
|
WriteLn('Algo : ', Algo); // bcPHP
|
|
WriteLn('AlgoName : ', AlgoName); // bcrypt
|
|
WriteLn('Cost : ', Cost); // 12
|
|
WriteLn('Salt : ', BCryptSalt); // GuC.Gk2YDsp8Yvga.IuSNO
|
|
WriteLn('Hash : ', BCryptHash); // WM0fxEIsAEaWC1hqEI14Wa.7Ps3iYFq
|
|
end;
|
|
|
|
Hash := '$2a$12$GuC.Gk2YDsp8Yvga.IuSNOWM0fxEIsAEaWC1hqEI14Wa.7Ps3iYFq';
|
|
PasswordInfo := BCrypt.HashGetInfo(Hash);
|
|
with PasswordInfo do
|
|
begin
|
|
WriteLn('Algo : ', Algo); // bcBSD
|
|
WriteLn('AlgoName : ', AlgoName); // bcrypt
|
|
WriteLn('Cost : ', Cost); // 12
|
|
WriteLn('Salt : ', BCryptSalt); // GuC.Gk2YDsp8Yvga.IuSNO
|
|
WriteLn('Hash : ', BCryptHash); // WM0fxEIsAEaWC1hqEI14Wa.7Ps3iYFq
|
|
end;
|
|
BCrypt.Free;
|
|
end;
|
|
```
|
|
NeedsRehash
|
|
```pascal
|
|
var
|
|
BCrypt : TBCryptHash;
|
|
Hash : AnsiString;
|
|
Rehash : Boolean;
|
|
begin
|
|
BCrypt := TBCryptHash.Create;
|
|
Hash := '$2a$12$GuC.Gk2YDsp8Yvga.IuSNOWM0fxEIsAEaWC1hqEI14Wa.7Ps3iYFq';
|
|
Rehash := BCrypt.NeedsRehash(Hash); // false
|
|
Rehash := BCrypt.NeedsRehash(Hash, 14); // true
|
|
Hash := '$2y$14$GuC.Gk2YDsp8Yvga.IuSNOWM0fxEIsAEaWC1hqEI14Wa.7Ps3iYFq';
|
|
Rehash := BCrypt.NeedsRehash(Hash); // true
|
|
Rehash := BCrypt.NeedsRehash(Hash, 14); // false
|
|
BCrypt.Free;
|
|
end;
|
|
```
|
|
### Evolution
|
|
This has had quite the evolution.
|
|
|
|
[FreeBSD crypt.c](https://svnweb.freebsd.org/base/stable/10/lib/libcrypt/crypt.c?revision=273043&view=markup "FreeBSD crypt.c")
|
|
|
|
[BCrypt for Delphi](https://github.com/JoseJimeniz/bcrypt-for-delphi "BCrypt for Delphi")
|
|
|
|
[BCrypt for Delphi, Lazarus, FPC](https://github.com/PonyPC/BCrypt-for-delphi-lazarus-fpc "BCrypt for Delphi, Lazarus, FPC")
|
|
|
|
[PHP password.c](https://github.com/php/php-src/blob/master/ext/standard/password.c "PHP password.c") For the verify logic.
|
|
|
|
To here.
|