commit
a37bbdc5d6
|
@ -1,4 +1,6 @@
|
||||||
*.o
|
*.o
|
||||||
*.ppu
|
*.ppu
|
||||||
*~
|
*~
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
|
49
BCrypt.pas
49
BCrypt.pas
|
@ -247,9 +247,8 @@ end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
Uses
|
||||||
Math,
|
Math; // @Todo : Remove and use Renegade.Random
|
||||||
RegExpr;
|
|
||||||
|
|
||||||
constructor TBCryptHash.Create;
|
constructor TBCryptHash.Create;
|
||||||
begin
|
begin
|
||||||
|
@ -503,8 +502,8 @@ end;
|
||||||
|
|
||||||
function TBCryptHash.FormatPasswordHash(const Salt, Hash: TBytes; Cost : Byte; HashType : THashTypes): AnsiString;
|
function TBCryptHash.FormatPasswordHash(const Salt, Hash: TBytes; Cost : Byte; HashType : THashTypes): AnsiString;
|
||||||
var
|
var
|
||||||
saltString: ansistring;
|
SaltString: ansistring;
|
||||||
hashString: ansistring;
|
HashString: ansistring;
|
||||||
HashPrefix : AnsiString;
|
HashPrefix : AnsiString;
|
||||||
begin
|
begin
|
||||||
case HashType of
|
case HashType of
|
||||||
|
@ -515,9 +514,9 @@ begin
|
||||||
HashPrefix := '2y';
|
HashPrefix := '2y';
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
saltString := BsdBase64Encode(Salt, Length(Salt));
|
SaltString := BsdBase64Encode(Salt, Length(Salt));
|
||||||
hashString := BsdBase64Encode(Hash, Length(MagicText) * 4 - 1);
|
HashString := BsdBase64Encode(Hash, Length(MagicText) * 4 - 1);
|
||||||
Result := Format('$%s$%d$%s%s', [HashPrefix, Cost, saltString, hashString]);
|
Result := Format('$%s$%d$%s%s', [HashPrefix, Cost, SaltString, HashString]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TBCryptHash.getRandomBlockFileName : AnsiString;
|
function TBCryptHash.getRandomBlockFileName : AnsiString;
|
||||||
|
@ -737,19 +736,28 @@ end;
|
||||||
|
|
||||||
function TBCryptHash.VerifyHash(const Password, Hash : AnsiString) : Boolean;
|
function TBCryptHash.VerifyHash(const Password, Hash : AnsiString) : Boolean;
|
||||||
var
|
var
|
||||||
RegexObj: TRegExpr;
|
WorkingBcryptHash, Salt : AnsiString;
|
||||||
WorkingBcryptHash : AnsiString;
|
HashCounter, ResultStatus, BCryptCost : Byte;
|
||||||
HashCounter, ResultStatus, Cost : Byte;
|
|
||||||
HashType : THashTypes;
|
HashType : THashTypes;
|
||||||
|
PasswordInfo :RTPasswordInformation;
|
||||||
Begin
|
Begin
|
||||||
ResultStatus := 0;
|
ResultStatus := 0;
|
||||||
RegexObj := TRegExpr.Create;
|
try
|
||||||
RegexObj.Expression := '^(\$2\w{1}\$)(\d{2})\$([\./0-9A-Za-z]{22})';
|
PasswordInfo := HashGetInfo(Hash);
|
||||||
if RegexObj.Exec(Hash) then
|
except
|
||||||
|
on e: EHash do
|
||||||
begin
|
begin
|
||||||
HashType := ResolveHashType(RegexObj.Match[1]);
|
Result := False;
|
||||||
Cost := StrToInt(RegexObj.Match[2]);
|
Exit;
|
||||||
WorkingBcryptHash := Crypt(Password, RegexObj.Match[3], Cost, HashType);
|
end;
|
||||||
|
end;
|
||||||
|
with PasswordInfo do
|
||||||
|
begin
|
||||||
|
HashType := Algo;
|
||||||
|
BCryptCost := Cost;
|
||||||
|
Salt := BCryptSalt;
|
||||||
|
end;
|
||||||
|
WorkingBcryptHash := Crypt(Password, Salt, BCryptCost, HashType);
|
||||||
if (Length(WorkingBcryptHash) < 60) or (Length(WorkingBcryptHash) > 60) then
|
if (Length(WorkingBcryptHash) < 60) or (Length(WorkingBcryptHash) > 60) then
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
|
@ -769,12 +777,9 @@ Begin
|
||||||
values. }
|
values. }
|
||||||
ResultStatus := ResultStatus or (ord(WorkingBcryptHash[HashCounter]) xor ord(Hash[HashCounter]));
|
ResultStatus := ResultStatus or (ord(WorkingBcryptHash[HashCounter]) xor ord(Hash[HashCounter]));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result := (ResultStatus = 0);
|
Result := (ResultStatus = 0);
|
||||||
end
|
|
||||||
else begin
|
|
||||||
Result := False;
|
|
||||||
end;
|
|
||||||
RegexObj.Free;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TBCryptHash.NeedsRehash(const BCryptHash : AnsiString) : Boolean; overload;
|
function TBCryptHash.NeedsRehash(const BCryptHash : AnsiString) : Boolean; overload;
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Change Log
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||||
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
|
||||||
|
## [0.1.0] - 2016-11-03
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Changelog
|
||||||
|
- Started using [semver](http://semver.org/) for versioning.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Removed regex logic for getting the password's current salt, because come on.
|
||||||
|
- Make use of object RTPasswordInformation to extract information from hash for verifing logic.
|
||||||
|
|
||||||
|
|
26
README.md
26
README.md
|
@ -9,14 +9,30 @@ If you try to verify a $2a$ password with PHP it will verify, but if you run the
|
||||||
Tested with :
|
Tested with :
|
||||||
* Free Pascal
|
* Free Pascal
|
||||||
* 2.6.4
|
* 2.6.4
|
||||||
* (Linux, Gentoo)
|
* Linux
|
||||||
* (Linux, Raspbian)
|
* Gentoo, 2.2-Current-x64
|
||||||
|
* Raspbian
|
||||||
* 3.0.0
|
* 3.0.0
|
||||||
* (Linux, Gentoo)
|
* Linux
|
||||||
* (Win10, 64bit)
|
* Gentoo, 2.2-Current-x64
|
||||||
|
* FreeBSD
|
||||||
|
* 12.0-CURRENT-x64
|
||||||
|
* Windows
|
||||||
|
* Windows 10-x64
|
||||||
* PHP
|
* PHP
|
||||||
|
* 5.5.x
|
||||||
|
* 5.5.38-pl0-gentoo
|
||||||
|
* 5.6.x
|
||||||
* 5.6.20-pl0-gentoo
|
* 5.6.20-pl0-gentoo
|
||||||
* 7.0.6_rc1-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
|
### Usage
|
||||||
```pascal
|
```pascal
|
||||||
|
|
Loading…
Reference in New Issue