Delphi XE中的SHA1哈希
我正在实现XML数字签名。我从一些小步骤开始,所以现在我想解决SHA-1哈希的问题 关于这一点,有很多问题,因此: …可能更多。但是,我使用的是DelphiXE。到目前为止,我已经尝试过LockBox 2(Songbeamer和Sourceforge版本)、LockBox 3、DCPCrypto2和其他一些(使用Windows加密功能的易于使用的单元) 我准备了一个小型试验台,提供以下信息: 锁箱2Delphi XE中的SHA1哈希,delphi,cryptography,delphi-xe,sha1,Delphi,Cryptography,Delphi Xe,Sha1,我正在实现XML数字签名。我从一些小步骤开始,所以现在我想解决SHA-1哈希的问题 关于这一点,有很多问题,因此: …可能更多。但是,我使用的是DelphiXE。到目前为止,我已经尝试过LockBox 2(Songbeamer和Sourceforge版本)、LockBox 3、DCPCrypto2和其他一些(使用Windows加密功能的易于使用的单元) 我准备了一个小型试验台,提供以下信息: 锁箱2 FAILED: 1 ('abc') Got: '9f04f41a848
FAILED: 1 ('abc')
Got: '9f04f41a848514162050e3d68c1a7abb441dc2b5'
Expected: 'a9993e364706816aba3e25717850c26c9cd0d89d'
FAILED: 2 ('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')
Got: '51d7d8769ac72c409c5b0e3f69c60adc9a039014'
Expected: '84983e441c3bd26ebaae4aa1f95129e5e54670f1'
FAILED: 1 ('abc')
Got: '9f04f41a848514162050e3d68c1a7abb441dc2b5'
Expected: 'a9993e364706816aba3e25717850c26c9cd0d89d'
FAILED: 2 ('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')
Got: '51d7d8769ac72c409c5b0e3f69c60adc9a039014'
Expected: '84983e441c3bd26ebaae4aa1f95129e5e54670f1'
锁箱3
FAILED: 1 ('abc')
Got: '9f04f41a848514162050e3d68c1a7abb441dc2b5'
Expected: 'a9993e364706816aba3e25717850c26c9cd0d89d'
FAILED: 2 ('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')
Got: '51d7d8769ac72c409c5b0e3f69c60adc9a039014'
Expected: '84983e441c3bd26ebaae4aa1f95129e5e54670f1'
DCPCrypto2
FAILED: 1 ('abc')
Got: '9f04f41a848514162050e3d68c1a7abb441dc2b5'
Expected: 'a9993e364706816aba3e25717850c26c9cd0d89d'
FAILED: 2 ('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')
Got: '51d7d8769ac72c409c5b0e3f69c60adc9a039014'
Expected: '84983e441c3bd26ebaae4aa1f95129e5e54670f1'
FAILED: 1 ('abc')
Got: '9f04f41a848514162050e3d68c1a7abb441dc2b5'
Expected: 'a9993e364706816aba3e25717850c26c9cd0d89d'
FAILED: 2 ('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')
Got: '51d7d8769ac72c409c5b0e3f69c60adc9a039014'
Expected: '84983e441c3bd26ebaae4aa1f95129e5e54670f1'
散列
Test 1 passes
Test 2 passes
您是否成功地在Delphi XE下编译了上述库,并使它们给出了适当的值?我对DCPCrypt2SelfTest
过程特别感兴趣
编辑:我添加了固定源代码。非常感谢大家的帮助。期望值是ANSI字符串,而得到的哈希值是unicode字符串吗?莱昂纳多,我想你的问题是当你使用函数对
字符串进行哈希时,你传递的是字节数组(缓冲区)。因此,当您在Delphi XE中传递abc
字符串时,您正在散列一个如下的缓冲区61 00 62 00 63 00
(十六进制表示)
检查此示例应用程序,它使用Jwscl库中的Windows加密函数(JEDI Windows安全代码库)
本报税表
abc
AnsiString
A9993E364706816ABA3E25717850C26C9CD0D89D
abcdbcdecdefefgefghghighijhijjjklmnlmnomnopnopq
AnsiString
84983E441CBD26EBAAE4AA1F95129E54670F1
abc
unicode
9F04F41A8414162005E3D68C1A7ABB441DC2B5
abcdbcdecdefefgefghghighijhijjjklmnlmnomnopnopq
Unicode
51D7D8769AC72C409C5B0E3F69C60ADC9A039014我的Cygwin命令提示符告诉我确实是Unicode让你困惑:
~$ printf 'a\0b\0c\0' | sha1sum
9f04f41a848514162050e3d68c1a7abb441dc2b5 *-
~$ printf 'abc' | sha1sum
a9993e364706816aba3e25717850c26c9cd0d89d *-
好吧,这就是Unicode问题。以防你想知道,这是我的Unit1.pas源代码。你需要一张有备忘录和按钮的表格。需要DCPCrypt2、LockBox2、LockBox3和散列单元
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, LbCipher, LbClass, StdCtrls, DCPcrypt2, DCPsha1, Hashes,
uTPLb_CryptographicLibrary, uTPLb_BaseNonVisualComponent, uTPLb_Hash;
type
THashProc = reference to procedure(src: AnsiString; var output: AnsiString);
TForm1 = class(TForm)
Memo1: TMemo;
btnTest: TButton;
function Display(Buf: TBytes): String;
procedure LockBox2Test;
procedure LockBox3Test;
procedure DCPCrypto2Test;
procedure HashesTest;
procedure btnTestClick(Sender: TObject);
private
{ Private declarations }
procedure RunTests(Name: String; HashFunc: THashProc);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses uTPLb_StreamUtils;
{$R *.dfm}
procedure TForm1.btnTestClick(Sender: TObject);
begin
LockBox2Test;
LockBox3Test;
DCPCrypto2Test;
HashesTest;
end;
procedure TForm1.DCPCrypto2Test;
begin
RunTests('DCPCrypto2', procedure(src: AnsiString; var output: AnsiString)
var
Digest: TSHA1Digest;
Bytes : TBytes;
SHA1 : TDCP_sha1;
begin
SHA1 := TDCP_sha1.Create(nil);
SHA1.Init;
SHA1.UpdateStr(src);
SHA1.Final(Digest);
SHA1.Destroy;
SetLength(Bytes, 20);
Move(Digest, Bytes[0], 20);
output := Form1.Display(Bytes);
end);
end;
function TForm1.Display(Buf: TBytes): String;
var
i: Integer;
begin
Result := '';
for i := 0 to 19 do
Result := Result + Format('%0.2x', [Buf[i]]);
Result := LowerCase(Trim(Result));
end;
procedure TForm1.HashesTest;
begin
RunTests('Hashes', procedure(src: AnsiString; var output: AnsiString)
begin
output := CalcHash2(src, haSHA1)
end)
end;
procedure TForm1.LockBox2Test;
begin
RunTests('LockBox2', procedure(src: AnsiString; var output: AnsiString)
var
Digest: TSHA1Digest;
Bytes : TBytes;
SHA1 : TLbSHA1;
begin
SHA1 := TLbSHA1.Create(nil);
SHA1.HashStringA(src);
SHA1.GetDigest(Digest);
SHA1.Destroy;
SetLength(Bytes, 20);
Move(Digest, Bytes[0], 20);
output := Form1.Display(Bytes);
end);
end;
procedure TForm1.LockBox3Test;
begin
RunTests('LockBox3', procedure(src: AnsiString; var output: AnsiString)
var
Digest: TSHA1Digest;
bytes : TBytes;
P, Sz: integer;
aByte: byte;
s: string;
SHA1 : THash;
Lib : TCryptographicLibrary;
begin
Lib := TCryptographicLibrary.Create(nil);
SHA1 := THash.Create(nil);
SHA1.CryptoLibrary := Lib;
SHA1.HashId := 'native.hash.SHA-1';
SHA1.Begin_Hash;
SHA1.HashAnsiString(src);
if not assigned(SHA1.HashOutputValue) then
output := 'nil'
else
begin
SetLength(Bytes, 20);
Sz := SHA1.HashOutputValue.Size;
if Sz <> 20 then
output := Format('wrong size: %d', [Sz])
else
begin
P := 0;
SHA1.HashOutputValue.Position := 0;
while SHA1.HashOutputValue.Read(aByte, 1) = 1 do
begin
bytes[P] := aByte;
Inc(P);
end;
output := Form1.Display(Bytes);
end;
end;
SHA1.Destroy;
Lib.Destroy;
end)
end;
procedure TForm1.RunTests(Name: String; HashFunc: THashProc);
var
i: Integer;
Tests: array [1 .. 2, 1 .. 2] of AnsiString;
src, res: AnsiString;
expected: String;
begin
// http://www.nsrl.nist.gov/testdata/
Tests[1][1] := 'abc';
Tests[1][2] := 'a9993e364706816aba3e25717850c26c9cd0d89d';
Tests[2][1] := 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq';
Tests[2][2] := '84983e441c3bd26ebaae4aa1f95129e5e54670f1';
Memo1.Lines.Add('');
Memo1.Lines.Add('**' + Name + '**');
Memo1.Lines.Add('');
for i := 1 to 2 do
begin
src := Tests[i][1];
expected := Tests[i][2];
HashFunc(src, res);
res := Trim(LowerCase(res));
if res = expected then
begin
Memo1.Lines.Add(Format(' Test %d passes', [i]))
end
else
begin
Memo1.Lines.Add(Format(' FAILED: %d (''%s'') ', [i, src]));
Memo1.Lines.Add(Format(' Got: ''%s''', [res]));
Memo1.Lines.Add(Format(' Expected: ''%s''', [expected]));
end;
end;
end;
end.
单元1;
接口
使用
窗口、消息、系统工具、变体、类、图形、控件、窗体、,
对话框,LbCipher,LbClass,StdCtrls,DCPcrypt2,DCPsha1,散列,
uTPLb_加密库、uTPLb_基本非可视组件、uTPLb_哈希;
类型
Thashroc=程序参考(src:AnsiString;var输出:AnsiString);
TForm1=类(TForm)
备忘录1:TMemo;
b测试:t按钮;
功能显示(Buf:T字节):字符串;
程序锁盒2测试;
程序锁盒3测试;
程序DCPCrypto2Test;
程序测试;
程序btnTestClick(发送方:ToObject);
私有的
{私有声明}
过程运行测试(名称:String;HashFunc:THashProc);
公众的
{公开声明}
结束;
变量
表1:TForm1;
实施
使用uTPLb_StreamUtils;
{$R*.dfm}
程序TForm1.btnTestClick(发送方:ToObject);
开始
LockBox2Test;
锁盒3测试;
dcpCrypto2测试;
哈希斯特;
结束;
程序TForm1.dcpCrypto2测试;
开始
运行测试('DCPCrypto2',过程(src:AnsiString;var输出:AnsiString)
变量
文摘:TSHA1Digest;
字节:TBytes;
SHA1:TDCP_SHA1;
开始
SHA1:=TDCP_SHA1.Create(nil);
SHA1.Init;
SHA1.Updatest(src);
SHA1.最终(摘要);
SHA1.破坏;
SetLength(字节,20);
移动(摘要,字节[0],20);
输出:=Form1.显示(字节);
(完),;
结束;
函数TForm1.Display(Buf:TBytes):字符串;
变量
i:整数;
开始
结果:='';
对于i:=0到19 do
结果:=结果+格式('%0.2x',[Buf[i]]);
结果:=小写(Trim(Result));
结束;
程序TForm1.HashesTest;
开始
运行测试('hash',过程(src:AnsiString;var输出:AnsiString)
开始
输出:=CalcHash2(src,haSHA1)
(完)
结束;
程序t用于M1.Lockbox2测试;
开始
运行测试('LockBox2',过程(src:AnsiString;var输出:AnsiString)
变量
文摘:TSHA1Digest;
字节:TBytes;
SHA1:TLbSHA1;
开始
SHA1:=TLbSHA1.Create(nil);
SHA1.HashStringA(src);
SHA1.获取摘要(摘要);
SHA1.破坏;
SetLength(字节,20);
移动(摘要,字节[0],20);
输出:=Form1.显示(字节);
(完),;
结束;
程序TForm1.Lockbox3测试;
开始
运行测试('LockBox3',过程(src:AnsiString;var输出:AnsiString)
变量
文摘:TSHA1Digest;
字节:TBytes;
P、 Sz:整数;
aByte:字节;
s:字符串;
SHA1:THash;
Lib:tcryptographics库;
开始
Lib:=tcryptographicslibrary.Create(nil);
SHA1:=THash.Create(nil);
SHA1.CryptoLibrary:=Lib;
SHA1.HashId:=“native.hash.SHA-1”;
SHA1.Begin_Hash;
SHA1.HashAnsiString(src);
如果未分配(SHA1.HashOutputValue),则
输出:='nil'
其他的
开始
SetLength(字节,20);
Sz:=SHA1.HashOutputValue.Size;
如果是Sz 20那么
输出:=格式('错误大小:%d',[Sz])
其他的
开始
P:=0;
SHA1.HashOutputValue.Position:=0;
而SHA1.HashOutputValue.Read(aByte,1)=1 do
开始
字节[P]:=aByte;
公司(P),;
结束;
输出:=Form1.显示(字节);
结束;
结束;
SHA1.破坏;
自毁;
(完)
结束;
过程TForm1.RunTests(名称:String;HashFunc:THashProc);
变量
i:整数;
测试:AnsiString的数组[1..2,1..2];
src,res:AnsiString;
应为:字符串;
开始
// http://www.nsrl.nist.gov/testdata/
测试[1][1]:=“abc”;
测试[1][2]:=“a9993e364706816aba3e25717850c26c9cd0d89d”;
测试[2][1]:=“ABCDBCDECDEFDEFGEFGHFGHIGHIJHIJHIJKIJKLJKLMNLMNOMNOPQ”;
测试[2][2]