3

Spring4D 库有密码学类,但是我无法让它们按预期工作。我可能错误地使用它们,但是缺乏任何例子使它变得困难。

例如在网站https://quickhash.com/hash-sha256-online上,我可以对单词“test”进行散列以生成以下散列:

9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

使用 Spring4D 库,以下代码生成不同的哈希:

CreateSHA256.ComputeHash('test').ToString;

结果是:

9EFEA1AEAC9EDA04A892885A65FDAE0E6D9BE8C9FC96DA76D31B929262E12B1D

除了大写/小写,它完全是一个不同的哈希。我知道一定是做错了什么,但同样没有使用示例,所以我一直坚持如何做到这一点。

4

3 回答 3

9

散列算法对二进制数据进行操作,通常使用字节数组表示。

不幸的是,您使用的两种资源都提供了散列文本的能力。为了散列文本,您首先需要将文本转换为二进制。为此,需要选择编码。两种方法都没有明确说明该选择是什么。

当我使用这个 Delphi 代码时:

LowerCase(CreateSHA256.ComputeHash(TEncoding.UTF8.GetBytes('test')).ToString)

我得到的哈希值与您的问题中出现的哈希值相同。

我敦促您永远不要尝试加密/散列文本,而是将这些操作视为对二进制文件进行操作。始终使用显式编码,然后加密/散列编码产生的字节数组。

我在这里选择了 UTF-8 编码,因为它是一个完整的 Unicode 编码,并且在空间方面往往是有效的。但是,我认为您的在线编码器不使用 UTF-8。实际上我不知道它使用什么编码,这件事还不清楚。这当然是文本不同于二进制的老问题。

在我看来,这是您使用的 Delphi 库的一个设计缺陷,它允许您在没有明确选择编码的情况下散列文本。如果这个库必须提供一个散列文本的函数,那么它应该要求调用者提供一个额外的TEncoding参数。

于 2014-12-01T08:13:36.730 回答
4

内部没有进行转换,因此它对每个字符至少 2 个字节的 UnicodeString 进行哈希处理。

如果您想要与页面上相同的结果,则必须使用 UTF8Encode 或直接作为 AnsiString 传递。

但是我尝试了一些包含不同 unicode 字符的字符串,页面返回了不同的结果。所以我不太确定他们如何处理那里的字符串。我想这是一个代码页的事情。

编辑:如果您使用此页面http://www.xorbin.com/tools/sha256-hash-calculator,它会使用 UTF8Encode 生成与 TSHA256 相同的哈希。

于 2014-12-01T07:59:17.577 回答
0

您使用的是哪种类型的字符串?您使用 AnsiString 还是 WideString(Unicode 字符串)。Delphi 2009 和更新版本默认使用 WideString。

为什么字符串类型很重要?所有哈希算法都对原始字节数据进行操作,因此如果字符串的每个字符都存储在一个内存字节(AnsiString)或多个内存字节(WideString)中,这一点很重要。

于 2014-12-01T06:20:43.770 回答