当前位置: 首页 > news >正文

Delphi HMAC算法

1. 前言

        今天做一个三方接口,接口文档描述签名采用MD5,但是实际测试过程中,始终校验不通过,经过和三方沟通,才知道采用的是HMAC-MD5。由于Delphi7没有对HMAC的支持,则采用XE版本来支持。本次使用Delphi XE 10.3.3、Delphi 7来实现。

        HMAC 散列消息认证码 (Hash-based Message Authentication Code),它是一种基于加密哈希函数和共享密钥的消息认证协议。它是一种给消息加上数字签名的方法,这个签名是根据消息内容和一个共享密钥生成的,只有知道密钥的人才能生成或验证这个签名。
        HMAC - https://baike.baidu.com/item/hmac/7307543
        在线验证 https://www.btool.cn/hmac-generator

2. Delphi XE 10.3.3 实现动态库

2.1 工程文件 hmactool.dpr

library hmactool;{HMAC 散列消息认证码 (Hash-based Message Authentication Code)它是一种基于加密哈希函数和共享密钥的消息认证协议。它是一种给消息加上数字签名的方法,这个签名是根据消息内容和一个共享密钥生成的,只有知道密钥的人才能生成或验证这个签名。HMAC - https://baike.baidu.com/item/hmac/7307543在线验证 https://www.btool.cn/hmac-generator
}usesWinapi.Windows,System.SysUtils,System.Classes,InterfaceDll in 'InterfaceDll.pas';{$R *.res}exportsdll_hmac_md5,dll_hmac_sha1,dll_hmac_sha2;procedure DLLHandler(Reason: integer);
varbuf: array[0..1023] of char;
begincase Reason ofDLL_PROCESS_DETACH: //释放DLL时beginend;DLL_Process_Attach: //加载DLL时beginend;DLL_Thread_Attach: //主进程创建一个新线程时beginend;DLL_Thread_Detach: //主进程结束一个线程时beginend;end;
end;beginDLLProc := @DLLHandler;DLLHandler(DLL_Process_Attach);
end.

2.2 接口文件 InterfaceDll.pas

unit InterfaceDll;interfaceusesSystem.SysUtils, System.Hash;varErrInfo: WideString;function dll_hmac_md5(sIn, sKey: PWideChar; var sOut: PWideChar): Byte; stdcall;function dll_hmac_sha1(sIn, sKey: PWideChar; var sOut: PWideChar): Byte; stdcall;function dll_hmac_sha2(iType: Byte; sIn, sKey: PWideChar; var sOut: PWideChar): Byte; stdcall;implementationfunction dll_hmac_md5(sIn, sKey: PWideChar; var sOut: PWideChar): Byte; stdcall;
varKey, Data: WideString;Hash: THashMD5;HMAC: WideString;
beginData := Trim(sIn);Key:= Trim(sKey);Hash := THashMD5.Create;HMAC := Hash.GetHMAC(Data, Key);sOut:= PWideChar(HMAC);result:= 0;
end;function dll_hmac_sha1(sIn, sKey: PWideChar; var sOut: PWideChar): Byte; stdcall;
varKey, Data: WideString;Hash: THashSHA1;HMAC: WideString;
beginData := Trim(sIn);Key:= Trim(sKey);Hash := THashSHA1.Create;HMAC := Hash.GetHMAC(Data, Key);sOut:= PWideChar(HMAC);result:= 0;
end;function dll_hmac_sha2(iType: Byte; sIn, sKey: PWideChar; var sOut: PWideChar): Byte; stdcall;
varKey, Data: WideString;Hash: THashSHA2;HMAC: WideString;
beginData := Trim(sIn);Key:= Trim(sKey);Hash := THashSHA2.Create(THashSHA2.TSHA2Version(iType));HMAC := Hash.GetHMAC(Data, Key, THashSHA2.TSHA2Version(iType));sOut:= PWideChar(HMAC);result:= 0;
end;end.

3. Delphi 7 实现Demo

3.1 工程文件 D7Demo.dpr

program D7Demo;usesForms,uDemo in 'uDemo.pas' {FrmMain};{$R *.res}beginApplication.Initialize;Application.CreateForm(TFrmMain, FrmMain);Application.Run;
end.

3.2 窗体代码 uDemo.pas

unit uDemo;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ComCtrls;constdllname= 'hmactool.dll';typeTFrmMain = class(TForm)redt1: TRichEdit;btn1: TButton;edt1: TEdit;edt2: TEdit;lbl1: TLabel;lbl2: TLabel;lbl3: TLabel;btn2: TButton;grp1: TGroupBox;btn3: TButton;rb1: TRadioButton;rb2: TRadioButton;rb3: TRadioButton;rb4: TRadioButton;rb5: TRadioButton;rb6: TRadioButton;procedure btn1Click(Sender: TObject);procedure btn2Click(Sender: TObject);procedure btn3Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;function dll_hmac_md5(pIn, pKey: PWideChar; var pOut: PWideChar): Byte; stdcall; external dllname;function dll_hmac_sha1(sIn, sKey: PWideChar; var sOut: PWideChar): Byte; stdcall; external dllname;function dll_hmac_sha2(iType: Byte; sIn, sKey: PWideChar; var sOut: PWideChar): Byte; stdcall; external dllname;varFrmMain: TFrmMain;implementation{$R *.dfm}procedure TFrmMain.btn1Click(Sender: TObject);
varsIn, sKey, sOut: WideString;pOut: PWideChar;iRet: Byte;
beginsIn:= StringReplace(Trim(redt1.Lines.Text),#13#10,'',[rfReplaceAll,rfIgnoreCase]);sKey:= Trim(edt2.Text);iRet:= dll_hmac_md5(PWideChar(sIn), PWideChar(sKey), pOut);if (iRet= 0) thenbeginedt1.Text:= UTF8Decode(pOut);end;
end;procedure TFrmMain.btn2Click(Sender: TObject);
varsIn, sKey, sOut: WideString;pOut: PWideChar;iRet: Byte;
beginsIn:= StringReplace(Trim(redt1.Lines.Text),#13#10,'',[rfReplaceAll,rfIgnoreCase]);sKey:= Trim(edt2.Text);iRet:= dll_hmac_sha1(PWideChar(sIn), PWideChar(sKey), pOut);if (iRet= 0) thenbeginedt1.Text:= UTF8Decode(pOut);end;
end;procedure TFrmMain.btn3Click(Sender: TObject);
varsIn, sKey, sOut: WideString;pOut: PWideChar;iType, iRet: Byte;
beginif rb1.Checked theniType:= 0else if rb2.Checked theniType:= 1else if rb3.Checked theniType:= 2else if rb4.Checked theniType:= 3else if rb5.Checked theniType:= 4else if rb6.Checked theniType:= 5;sIn:= StringReplace(Trim(redt1.Lines.Text),#13#10,'',[rfReplaceAll,rfIgnoreCase]);sKey:= Trim(edt2.Text);iRet:= dll_hmac_sha2(iType, PWideChar(sIn), PWideChar(sKey), pOut);if (iRet= 0) thenbeginedt1.Text:= UTF8Decode(pOut);end;
end;end.

4. 最终效果

        测试了MD5、SHA1、SHA224、SHA256、SHA384、SHA512、SHA512-224、SHA512-256都可行,以下就贴出其中三个效果图吧,其他就不贴了。

相关文章:

  • Spring常用注解
  • 大模型在轮状病毒肠炎预测及临床方案制定中的应用研究
  • 工厂能耗系统智能化解决方案 —— 安科瑞企业能源管控平台
  • AF3 create_alignment_db_sharded脚本create_shard函数解读
  • mysql删除表后重建表报错Tablespace exists
  • Grafana安装
  • 云服务器X86计算和Arm计算架构有什么区别?
  • 莒县第六实验小学:举行“阅读世界 丰盈自我”淘书会
  • Xilinx 7系列fpga在线升级和跳转
  • AF3 create_alignment_db_sharded脚本process_chunk函数解读
  • 视频设备轨迹回放平台EasyCVR利旧前端设备,打造智慧校园视频上云方案
  • Apifox 全面支持 LLMs.txt:让 AI 更好地理解你的 API 文档
  • python的import类与模块区别
  • windows上rabbitmq服务激活后 15672无法打开
  • 灰度共生矩阵(GLCM)简介
  • ROS2模块库概览
  • 20.3 使用技巧2
  • 低代码控件开发平台:飞帆中使用d3.js初尝
  • 数据结构(java)栈与队列
  • Chemical Review IF=51.4 综述 | 柔性机器人的当下与未来:材料、技术与应用的深度融合
  • 网站域名解析后多久能生效/百度手机端排名如何优化
  • 广州做网站建设的公司/网络推广的方式有哪些
  • 长沙seo行者seo09/免费seo网站自动推广
  • 迅驰互联网站建设网络推广怎么样/最新黑帽seo教程
  • 东莞 网站 建设 雕塑/网站搭建平台都有哪些
  • 微信开发在哪能看/百度seo优化多少钱