I was able to find two Bcrypt libraries that can be compiled for windows but I am struggling to compile them for Android in Delphi XE8.
The first one is https://github.com/chinshou/bcrypt-for-delphi which doesn't require any modifications to be compiled for Windows.
For the second one https://github.com/PonyPC/BCrypt-for-delphi-lazarus-fpc I had to make some minor adjustments in the checkPassword function to get the same result since it was FreePascal specific:
function checkPassword(const Str: string; const Hash: ansistring): boolean;
var
RegexObj: TRegEx;
match : TMatch;
Salt : String;
begin
RegexObj := TRegEx.Create('^\$2a\$10\$([\./0-9A-Za-z]{22})',[roIgnoreCase]);
match := RegexObj.Match(Hash);
if match.Success then
begin
Salt := Copy(match.Value,8,22);
Result := HashPassword(Str, Salt) = Hash;
end
else
begin
Result := False;
end;
end;
After changing the platform from Win to Android the first one shows a lot of errors since it depends on ComObj, Windows and ActiveX. The second one after replacing RegExpr with RegularExpressions and Types shows only conflicts that results from changes in the String variable. The code uses AnsiString, AnsiChar which I cannot just replace with String and Char since it affects the hashing function.
What am I missing? what other modifications should I do to replace the obsolete AnsiString and AnsiChar declarations, allowing the code to be compiled for Android?
The String declaration problem with the second library was caused by the move command in the HashPassword function
Move(password[1], key[0], Length(password));
since the size of the password variable changed after replacing the declaration from AnsiString to String. Replacing this with a simple for loop and Ord function fixes the problem although there is probably a more elegant way of doing it.
function HashPassword(const Str: string; const salt: string): string;
var
password: String ;
key, saltBytes, Hash: TBytes;
i: Integer;
begin
password := AnsiToUtf8(str);
SetLength(key, Length(password) + 1);
for i := 0 to length(password)-1 do
key[i]:=ord(password[i+1]);
key[high(key)] := 0;
saltBytes := BsdBase64Decode(salt);
Hash := CryptRaw(key, saltBytes);
Result := FormatPasswordHashForBsd(saltBytes, Hash);
end;
To summarize, the conversion of the second library to an Android compatible code requires the following changes:
modifying the regular expression code in the checkPassword function according to the code posted in the question
altering the uses section by replacing "RegExpr" with "RegularExpressions, Types"
replacing all declarations from AnsiString to String and AnsiChar to Char
modifying the HashPassword function as shown above