用于delphi XE8的多设备Bcrypt库

时间:2015-09-29 21:40:34

标签: android delphi bcrypt 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编译代码?

1 个答案:

答案 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函数,如上所示