delphi XE8 的多设备 Bcrypt 库
Multi-device Bcrypt library for delphi XE8
我找到了两个可以为 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?
编译代码
第二个库的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函数如上图
我找到了两个可以为 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?
编译代码第二个库的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函数如上图