我能够找到两个可以为windows编译的Bcrypt库但是我很难在Delphi XE8中为Android编译它们。
第一个是https://github.com/chinshou/bcrypt-for-delphi,它不需要为Windows编译任何修改。
对于第二个https://github.com/PonyPC/BCrypt-for-delphi-lazarus-fpc,我必须在checkPassword函数中做一些小的调整才能得到相同的结果,因为它是FreePascal特有的:
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;
将平台从Win更改为Android后,第一个显示了很多错误,因为它依赖于ComObj,Windows和ActiveX。使用RegularExpressions和Types替换RegExpr后的第二个仅显示changes in the String variable产生的冲突。代码使用AnsiString,AnsiChar,我不能用String和Char替换它,因为它会影响散列函数。
我错过了什么?我应该做些什么来修改过时的AnsiString和AnsiChar声明,允许为Android编译代码?
答案 0 :(得分:2)
第二个库的String声明问题是由HashPassword函数中的move命令引起的
Move(password[1], key[0], Length(password));
因为在将AnsiString的声明替换为String后,密码变量的大小发生了变化。用简单的for循环和Ord函数替换它可以解决问题,尽管可能有更优雅的方法。
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;
总而言之,将second library转换为Android兼容代码需要进行以下更改:
修改checkPassword函数中的正则表达式代码 根据问题中张贴的代码
通过替换" RegExpr"来改变用途部分使用" RegularExpressions,Types"
将所有声明从AnsiString替换为String并将AnsiChar替换为Char
修改HashPassword函数,如上所示