我需要哈希一个字符串,最好是SHA512,尽管它可能是SHA256,SHA1,MD5或CRC32。
我已经下载了Lockbox 3,在表单上放置了TCryptographicLibrary和THash组件,将Hash属性设置为SHA-512并使用以下代码生成测试结果:
procedure TForm1.Button1Click(Sender: TObject);
begin
Hash1.HashString('myhashtest');
Edit1.Text := Stream_To_AnsiString(Hash1.HashOutputValue);
end;
为了最好地说明问题,我已经使用在线哈希计算器,并且'myhashtest'的MD5哈希是ff91e22313f0a41b46719e7ee6f99451
,但是将我的测试程序中的哈希属性设置为MD5会导致ÿ‘â#ð¤Fqž~æù”Q
这显然是错的。我尝试使用其他Hash属性进行相同的测试,包括我想要的SHA512,并且它们都返回了垃圾。
我哪里错了?
答案 0 :(得分:3)
THash.HashOutputValue
是原始散列字节的流。似乎Stream_To_AnsiString()
只是将那些原始字节按原样复制到AnsiString
中,它不会以任何方式对字节进行编码。您正在寻找的是原始字节的十六进制编码版本。我知道LockBox有Stream_To_Base64()
函数(如this example所示),但我不知道它是否具有Stream_To_Hex()
类型的函数。如果没有,您可以轻松创建自己的,例如:
function Stream_To_Hex(Stream: TStream): AnsiString;
var
NumBytes, I: Integer;
B: Byte;
begin
NumBytes := Stream.Size - Stream.Position;
SetLength(Result, NumBytes * 2);
for I := 0 to NumBytes-1 do
begin
Stream.ReadBuffer(B, 1);
BinToHex(@B, @Result[(I*2)+1], 1);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Hash1.HashString('myhashtest');
Edit1.Text := Stream_To_Hex(Hash1.HashOutputValue);
end;
答案 1 :(得分:1)
许多加密函数“默默地”(即没有在文档中说明)输出并且需要Base64或十六进制编码的字符串(以及通常也是AnsiStrings)。这是因为加密文本可以包含任何数据,并且一旦开始将其视为“字符串”,字符串处理函数就可以轻易地阻塞它(例如,包含null的以null结尾的字符串)。通过对密码文本进行Base-64 / hex编码,您可以确保它是纯旧的ASCII字符,可以读取/写入旧代码。
如果您在密码代码或其方法参数中稍微挖掘一下,通常可以确定,并相应地转换字符串。