【问题标题】:Multi-device Bcrypt library for delphi XE8delphi XE8的多设备Bcrypt库
【发布时间】:2015-09-29 21:40:33
【问题描述】:

我能够找到两个可以为 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。将 RegExpr 替换为正则表达式和类型后的第二个仅显示由 changes in the String variable 引起的冲突。该代码使用了 AnsiString、AnsiChar,我不能只用 String 和 Char 替换它们,因为它会影响散列函数。

我错过了什么?我应该做哪些其他修改来替换过时的 AnsiString 和 AnsiChar 声明,以便为 Android 编译代码?

【问题讨论】:

  • 如果它需要 ActiveX,它不会适用于 Android 或任何其他平台。 ActiveX 只是严格意义上的 Windows。与另一个相同,您不能期望简单地将AnsiChar 替换为String 并期望它甚至可以在Windows 中工作。你最好找一个不同的库,比如 LockBox 10。
  • LockBox 10 是多平台的,并且支持 Blowfish:github.com/TurboPack/LockBox
  • 我提到的所有库都是 Windows,不仅是 ActiveX,而且代码的某些部分可以替换为 FMX 函数,这是我试图用第二个更兼容的库来实现的。我从没想过这个代码可以通过简单地替换字符串声明来工作,你从哪里得到这个想法?至于LockBox,我会试一试,它看起来很有前途。
  • 您在最后一段中的问题(“我遗漏了什么?”和“还有哪些其他修改...”)似乎表明您确实想重用您找到的第二个库,这就是我产生这个想法的地方。它是为 Windows 设计的,并且具有非常特定于 Windows 的内容。
  • 整个问题是关于重用这些库,但我仍然没想到它会像用 String 替换 AnsiString 一样简单,这是我在这两个问题之前的段落中写的。我们显然误解了对方。

标签: android delphi bcrypt delphi-xe8


【解决方案1】:

第二个库的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函数如上图

【讨论】:

  • 我觉得不合适。字符串是 UTF-16 编码的。你想要一个字节数组。文本和二进制不是一回事。
  • 拜托,你能把你的整个代码和所有的修改放在一起吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-11
  • 2023-03-13
  • 1970-01-01
  • 2015-10-08
  • 1970-01-01
相关资源
最近更新 更多