Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Catalog · How the catalog works

Random project

pascal_bcrypt

Free Pascal Implementation of BCrypt password hashing.

View on GitHub

Anyone may press Interesting, signed in or not. It helps others find this project.

Member rating

No ratings yet.

Sign in to rate this project.

README

Free Pascal BCrypt

Free Pascal 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
      1. .4
        • Linux
          • Gentoo, 2.2-Current-x64
          • Raspbian
      1. .0
        • Linux
          • Gentoo, 2.2-Current-x64
        • FreeBSD
      2. -CURRENT-x64
        • Windows
          • Windows 10-x64
      1. .1
        • Linux
          • Gentoo, 2.2-Current-x64
    • PHP
      1. .x
      2. .38-pl0-gentoo
      1. .x
      2. .20-pl0-gentoo
      3. .28-pl0-gentoo
      1. .x
      2. .6_rc1-pl0-gentoo
      3. .13-pl0-gentoo
      1. .x (dev)
      2. .0-dev-x64 (ZTS) 10/31/2016, Gentoo 2.2 Current
      3. .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, 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

BCrypt for Delphi

BCrypt for Delphi, Lazarus, FPC

PHP password.c For the verify logic.

To here.