在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
//****************************************************************************** //基于MD5算法的Hash MAC:实现 //****************************************************************************** //作者:Cai //日期:2011-10-25 //****************************************************************************** unit HMAC_MD5Class; interface uses MD5Class; type THMAC_MD5Context = record MD5Context: TMD5Context; Key : TBytes_64; InPad : TBytes_64; OutPad : TBytes_64; end; THMAC_MD5Class = Class protected FHash: TMD5Class; public constructor Create(); virtual; destructor Destroy; override; //=========基于MD5的Hash MAC算法:实现========== procedure HMAC_MD5Init(var Context: THMAC_MD5Context; sKey: string); procedure HMAC_MD5Update(var Context: THMAC_MD5Context; pInBuffer: PByte; iInBufLen: UINT4); procedure HMAC_MD5Final(var Digest: TMD5Digest; var Context: THMAC_MD5Context); end; implementation { THMAC_MD5Class } constructor THMAC_MD5Class.Create; begin FHash:=TMD5Class.Create; end; destructor THMAC_MD5Class.Destroy; begin FHash.Destroy; inherited; end; (*引用百科: HMAC引擎提供HMAC运算步骤: (1) 在密钥K后面添加0来创建一个字长为B的字符串。(例如,如果K的字长是20 字节,B=64字节,则K后会加入44个零字节0x00, 鉴别密钥的长度可以是小于等 于数据块字长的任何正整数值。应用程序中使用的密钥长度若是比B大,则首先 用使用散列函数H作用于它,然后用H输出的L长度字符串作为在HMAC中实际使用 的密钥。一般情况下,推荐的最小密钥K长度是L个字节。) (2) 将上一步生成的B字长的字符串与ipad做异或运算。 (3) 将数据流text填充至第二步的结果字符串中。 (4) 用H作用于第三步生成的数据流。 (5) 将第一步生成的B字长字符串与opad做异或运算。 (6) 再将第四步的结果填充进第五步的结果中。 (7) 用H作用于第六步生成的数据流,输出最终结果 *) //基于MD5的HMAC算法 (Hash-MAC算法) procedure THMAC_MD5Class.HMAC_MD5Init(var Context: THMAC_MD5Context; sKey: string); var TmpContext: TMD5Context; I, iKeyLen: UINT4; TmpKey: TMD5Digest; begin FillChar(Context, SizeOf(THMAC_MD5Context), 0); iKeyLen := Length(sKey); // if key is longer than 64 bytes reset it to key=MD5(key) if (iKeyLen > 64) then begin FHash.MD5Init(TmpContext); FHash.MD5Update(TmpContext, PByte(PChar(sKey)), iKeyLen); FHash.MD5Final(TmpKey, TmpContext); Move(TmpKey, Context.Key, 16);//SizeOf(TmpKey)); iKeyLen := SizeOf(TBytes_16); //16 end else begin Move(PChar(sKey)^, Context.Key, iKeyLen); end; (* start out by storing key in pads *) FillChar(Context.InPad , SizeOf(Context.InPad) , 0); FillChar(Context.OutPad, SizeOf(Context.OutPad), 0); for i:=0 to iKeyLen-1 do begin Context.InPad[i] := Context.key[i]; Context.OutPad[i] := Context.key[i]; end; (* XOR key with ipad and opad values *) for i:=0 to 64-1 do begin Context.InPad[i] := Context.InPad[i] xor $36; Context.OutPad[i] := Context.OutPad[i] xor $5C; end; // perform inner MD5 // init context for 1st * pass FHash.MD5Init(Context.MD5Context); //start with inner pad FHash.MD5Update(Context.MD5Context, @Context.InPad, 64); end; procedure THMAC_MD5Class.HMAC_MD5Update(var Context: THMAC_MD5Context; pInBuffer: PByte; iInBufLen: UINT4); begin //then text of datagram FHash.MD5Update(Context.MD5Context, pInBuffer, iInBufLen); end; procedure THMAC_MD5Class.HMAC_MD5Final(var Digest: TMD5Digest; var Context: THMAC_MD5Context); begin //finish up 1st pass FHash.MD5Final(Digest, Context.MD5Context); // perform outer MD5 //init context for 2nd * pass FHash.MD5Init(Context.MD5Context); //start with outer pad FHash.MD5Update(Context.MD5Context, @Context.OutPad, 64); //then results of 1st * hash FHash.MD5Update(Context.MD5Context, @Digest, 16); //finish up 2nd pass FHash.MD5Final(Digest, Context.MD5Context); end; end.
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论