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都可行,以下就贴出其中三个效果图吧,其他就不贴了。
相关文章:
Delphi HMAC算法
1. 前言 今天做一个三方接口,接口文档描述签名采用MD5,但是实际测试过程中,始终校验不通过,经过和三方沟通,才知道采用的是HMAC-MD5。由于Delphi7没有对HMAC的支持,则采用XE版本来支持。本次使用Delphi XE …...
Ubuntu服务器性能调优指南:从基础工具到系统稳定性提升
一、性能监控工具的三维应用 1.1 监控矩阵构建 通过组合工具搭建立体监控体系: # 实时进程监控 htop --sort-keyPERCENT_CPU# 存储性能采集 iostat -dx 2# 内存分析组合拳 vmstat -SM 1 | awk NR>2 {print "Active:"$5"MB Swpd:"$3"…...
深度解析C++开源OCR引擎:架构、编译优化与工业级部署指南
1. 引言:OCR技术演进与现状分析 光学字符识别(OCR)技术经历了从传统模式识别到深度学习的三代发展: 第一代:基于模板匹配(1970s-1990s) 第二代:特征提取+分类器(1990s-2010s) 第三代:端到端深度学习(2010s-至今) 当前工业界主流方案呈现"双轨制"发展态势…...
关于Newtonsoft.Json
历史 Newtonsoft.Json(也称为 Json.NET)是由 James Newton - King 开发的一个开源的 JSON 处理库,它于 2007 年首次发布。在早期,.NET 平台缺乏一个强大且灵活的 JSON 处理工具,Newtonsoft.Json 应运而生,…...
Spark-Sql编程(三)
一、数据加载与保存 通用方式:使用spark.read.load和df.write.save,通过format指定数据格式(如csv、jdbc、json等),option设置特定参数(jdbc格式下的url、user等),load和save指定路…...
CTF--好像需要管理员
一、原网页: 二、步骤: 1.扫描: 发现:robots.txt 2.打开robots.txt: 3.打开resul.php: 4.代码解析: if ($_GET[x]$password) //检查通过 URL 参数 x 传递的值是否等于变量 $password 的值 详…...
耀圣控制设备有限公司总经理李雨蔓的创业之路
破浪者李雨蔓:从零到行业标杆的铿锵之路 在浙江永嘉这片被誉为“中国泵阀之乡”的热土上,一位86年出生的女性企业家,用十年光阴书写了一段白手起家的传奇。她,是一曲关于勇气、智慧与匠心的赞歌。从技术员到行业标杆的缔造者&…...
Spring Boot JPA 开发之Not an entity血案
项目状况介绍 项目环境 JDK 21Spring Boot 3.4.3Hibernate: 6.6.13.Final项目描述 因为是微服务架构,项目层级如下 project-parent project-com project-A … project-X 其中: project-parent定义依赖库的版本project-com 定义了一些公用的方法和配置,包括持久层的配置。…...
什么是车规级MCU?STM32也能上车规级场景?
一、车规级MCU的定义 车规级MCU(Microcontroller Unit)是专为汽车电子系统设计的微控制器芯片,集成CPU、存储器、外设接口等功能模块,用于实现车辆控制、数据处理和实时响应。其核心特点包括: 高可靠性:需在…...
vue3.2 + element-plus 实现跟随input输入框的弹框,弹框里可以分组或tab形式显示选项
效果 基础用法(分组选项) 高级用法(带Tab栏) <!-- 弹窗跟随通用组件 SmartSelector.vue --> <template><div class"smart-selector-container"><el-popover :visible"visible" :w…...
go 指针接收者和值接收者的区别
go 指针接收者和值接收者的区别 指针接收者和值接收者的区别主要有两点: Go 中函数传参是传值,因此指针接收者传递的是接收者的指针拷贝,值接收者传递的是接收者的拷贝---在方法中指针接收者的变量会被修改,而值接收者的成员变量…...
部署qwen2.5-VL-7B
简单串行执行 from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor from qwen_vl_utils import process_vision_info import torch, time, threadingdef llm(model_path,promptNone,imageNone,videoNone,imagesNone,videosNone,max_new_tokens2048,t…...
Go:测试
go test 工具 go test是 Go 语言包的测试驱动程序 ,包依据特定约定组织 。包目录中以_test.go结尾的文件是go test编译对象,而非go build的编译目标 。 特殊测试函数 在*_test.go文件中有三种特殊函数 : 功能测试函数:以Test为…...
用微信小程序制作一个性行为同意协议系统
用微信小程序制作一个性行为同意协议系统 用微信小程序制作一个性行为同意协议系统,具备查询、修改、增加和演示的Web功能。首先,我需要明确这个系统的核心功能和法律合规性。性同意是一个敏感且法律相关的话题,必须确保系统的设计符合法律法…...
leetcode 122. Best Time to Buy and Sell Stock II
题目描述 这道题可以用贪心思想解决。 本文介绍用动态规划解决。本题分析方法与第121题一样,详见leetcode 121. Best Time to Buy and Sell Stock 只有一点区别。第121题全程只能买入1次,因此如果第i天买入股票,买之前的金额肯定是初始金额…...
FairyGUI图标文字合批失败的原因
1)FairyGUI图标文字合批失败的原因 2)为什么Cubemap的内存占用超高 3)如何找到网格某个切面的中心点 4)为什么SafeZone在倒屏后方向相反 这是第428篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了…...
C/C++ 通用代码模板
✅ C 语言代码模板(main.c) 适用于基础项目、算法竞赛或刷题: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <math.h>// 宏定义区 #define MAX_N 1000 #defi…...
void MainWindow::on_btnOutput_clicked()为什么我在QT里面没有connect,也能触发点击效果
在 Qt 中,即使你没有显式调用 connect 函数,某些信号(如按钮的 clicked() 信号)仍然可以触发槽函数。这是因为 Qt 提供了一种自动连接机制,称为 自动连接(Auto-Connection)。以下是可能的原因和…...
基于YOLO11的车牌识别分析系统
【包含内容】 【一】项目提供完整源代码及详细注释 【二】系统设计思路与实现说明 【三】系统数据统计与可视化分析支持 【技术栈】 ①:系统环境:Windows/macOS/Linux ②:开发环境:Python 3.8 ③:技术栈&#x…...
openwebui搭建mcp
1、升级ollama https://github.com/ollama/ollama/blob/main/docs/faq.md curl -fsSL https://ollama.com/install.sh | shOllama 启动后,设置外网访问_ollama 外部访问-CSDN博客 ubuntu安装deepseek-CSDN博客 sudo vim /etc/systemd/system/ollama.serviceEnvi…...
邀请函 | 知从科技邀您共赴2025上海车展
2025上海车展将于4月23日至5月2日在国家会展中心(上海)盛大举行。本届车展以 “科技智驾未来”为主题,共同展示新能源汽车、智能驾驶等领域的最新技术与成果。 知从科技将携行业领先的软件产品与技术服务亮相于本次展览会,全方位…...
ESP32开发工具链选择指南:ESP-IDF vs PlatformIO vs Arduino
1. 引言 ESP32作为乐鑫(Espressif)推出的一款高性能Wi-Fi & Bluetooth双模芯片,凭借其强大的性能和丰富的生态,在物联网(IoT)领域广受欢迎。然而,开发ESP32时面临的一个关键问题是…...
【JAVA】bat文件启动jar场景获取bat文件路径的方法
一、推荐方案:参数传递法 步骤1:修改BAT脚本 echo off java -jar -Dbat.file"%~f0" your-app.jar %*关键参数说明: %~f0:获取BAT文件的完整路径%*:传递所有原始参数 步骤2:Java代码获取参数 …...
OpenLayers:extent与view extent 介绍
一、范围的概念 1.什么是范围? 在Openlayers中范围(Extent)是用于表示地理空间区域的一种概念。它通常由一个数字数组构成,数组中的内容为:[最小x坐标,最小y坐标,最大x坐标,最大y坐…...
Python开发一个简单的软件系统
用Python语言实现,具备录入学生成绩、查询成绩和显示所有成绩等基本功能。以下是代码: # 用于存储学生成绩的字典,键是学生姓名,值是成绩 student_scores {} # 录入学生成绩的函数 def input_scores(): name input("…...
小草GrassRouter多5G聚合路由设备在应急公安消防行业的解决方案及重要作用
小草GrassRouter多5G聚合路由设备在应急、公安、消防等行业的解决方案及重要作用主要体现在以下几个方面,这些领域对通信的高可靠性、高带宽、低时延需求尤为突出,尤其在复杂环境或突发事件中需要保障指挥调度的实时性和稳定性: ** 一、行业…...
冒泡排序、插入排序、快速排序、堆排序、希尔排序、归并排序
目录 冒泡排序插入排序快速排序(未优化版本)快速排序(优化版本)堆排序希尔排序归并排序各排序时间消耗对比 冒泡排序 冒泡排序核心逻辑就是对数组从第一个位置开始进行遍历,如果发现该元素比下一个元素大,则交换位置,如果不大,就…...
JVM知识
JVM 内存模型 JVM的内存模型介绍一下 根据 JVM8 规范,JVM 运行时内存共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分。 JVM的内存结构主要分为以下几个部分: 方法区:存放类对象 Java 虚拟机栈:存放方法之间的调…...
Docker 中多个容器之间的通信
在 Docker 中,多个容器之间的通信可以通过以下几种主要方式实现,具体选择取决于网络需求、隔离性及管理复杂度: 一、自定义 Bridge 网络(推荐) 通过创建自定义的 Docker 网络,容器可以加入同一网络并通过容…...
docker desktop for windows 登录国内镜像仓库
在使用 Docker Desktop for Windows 时,如果你希望连接到国内的 Docker 镜像仓库(例如阿里云、腾讯云等),你可以通过配置 Docker 镜像加速器来实现。以下是一些步骤和示例,帮助你设置 Docker Desktop for Windows 以使…...
【blender小技巧】使用blender的Cats Blender Plugin插件将3D人物模型快速绑定或者修复为标准的人形骨骼
文章目录 前言绑定或者修复人形骨骼1、下载模型2、导入模型到blender中3、删除无用的相机和灯光3、导出模型并在unity中使用 专栏推荐完结 前言 有时候我们下载的3D人物模型,可能不带骨骼信息,或者带一些错乱的骨骼信息。这时候我们就可以使用blender将…...
视频压缩技术学习(不高明版本)
1. 压缩的本质与核心目标 视频压缩的核心在于去除冗余信息,包括空间冗余(相邻像素相关性)、时间冗余(连续帧相似性)以及视觉冗余(人眼感知特性)。通过算法优化,在保持可…...
在Vue项目中查询所有版本号为 1.1.9 的依赖包名 的具体方法,支持 npm/yarn/pnpm 等主流工具
以下是 在Vue项目中查询所有版本号为 1.1.9 的依赖包名 的具体方法,支持 npm/yarn/pnpm 等主流工具: 一、使用 npm 1. 直接过滤依赖树 npm ls --depth0 | grep "1.1.9"说明: npm ls --depth0:仅显示直接依赖…...
【Web前端技术】第一节—HTML简介
做出一个属于自己的网站! 云边有个稻草人-个人主页 为你,千千万万遍 ——哈桑 目录 一、网页 1.什么是网页? 2. 什么是 HTML? 3. 网页的形成 二、常用浏览器 1. 常用浏览器 2. 浏览器内核 三、Web标准(重点&…...
LINUX 416 路由转发1
那干脆先配置一下 boot目录必然是标准分区 配路由转发实验 路由器 计划新建3个虚拟机,分别是主机、节点a、节点b,都时间仅主机模式 路由器网卡IP: 节点a路由表 这次装载了附件,桌面安装模式,不用像 最小化安装模式那样折…...
【音视频开发】第四章 SDL音视频渲染
【音视频开发】第四章 SDL音视频渲染 文章目录 【音视频开发】第四章 SDL音视频渲染一、简介1.什么是 SDL 二、Windows 环境搭建三、SDL 子系统四、Window 显示1.SDL 视频显示函数简介2.窗口渲染结构体 五、SDL 事件1.通用事件结构体 SDL_Event2.事件类型 六、SDL 线程1.常用线…...
音频基础概念
声音 物体在一定的振动频率下产生了声音。声音可以被分解为不同频率不同强度正弦波的叠加。 声音三要素 声调 音调: 由发声体振动的频率决定,频率越高(振动越快)则音调越高,听起来就越“刺耳”,反之音调越低、听起…...
rust编程学习(二):复合数据类型
复合数据类型是由其他类型组合而成的类型。Rust的复合数据类型有元组、数组、结构体、枚举等, 通过一些简单的例子帮助大家快速了解Rust复合类型。 1 元组类型 元组类型是由一个或多个类型的元素组合成的复合类型,使用小括号“()”把所有元素放在一起。…...
学习笔记十四——一文看懂 Rust 迭代器
🌀 一文看懂 Rust 迭代器 📚 目录导航 什么是迭代器?为什么 Rust 到处都在用它?Rust 迭代器的底层逻辑是什么?适配器 vs 消费者:谁是主角?常见适配器:加工数据的全能工厂常见消费者…...
H.265硬件视频编码器xk265代码阅读 - 帧内预测
源代码地址: https://github.com/openasic-org/xk265 帧内预测具体逻辑包含在代码xk265\rtl\rec\rec_intra\intra_pred.v 文件中。 module intra_pred() 看起来是每次计算某个4x4块的预测像素值。 以下代码用来算每个pred_angle的具体数值,每个mode_i对应…...
贪心算法学习C++
1,跳跃游戏II 题目连接:45. 跳跃游戏 II - 力扣(LeetCode) 【题目描述】 在给定的一个nums数组中,nums[i]表示从当前i位置最多可以向后跳跃nums[i]个位置。问跳跃到最后 数组最后一个元素的最少跳跃次数?…...
Go 语言实现的简单 CMS Web
Go 语言实现的简单 CMS Web 以下是一个使用 Go 语言实现的简单 CMS Web 演示代码示例, 包含基本的内容管理功能: 项目结构 ### 项目结构 cms-demo/ ├── main.go ├── handlers/ ├── models/ ├── views/ │ ├── home.html │ ├─…...
Zookeeper选举机制
一、选举机制的核心原理 ZooKeeper的选举机制基于ZAB协议(ZooKeeper Atomic Broadcast),这是一种为分布式系统设计的原子广播协议。其核心目标是快速选举出Leader节点,并确保数据一致性。以下为关键原理: 1. 选举触发…...
安卓自定义build的apk文件名
android studio打包应用默认生成的apk名称是:app-release.apk 。 如果我们想修改生成的apk文件名,比如想放入版本号,比如想放入渠道号,又比如和打包时间有关联,那我们就需要能自动化生成可自定义的apk文件名ÿ…...
【Web APIs】JavaScript 操作多个元素 ④ ( 表格全选复选框案例 )
文章目录 一、核心要点解析 - 表格全选复选框案例1、案例需求2、复选框设置3、获取 全选复选框 和 普通复选框4、设置 全选复选框 逻辑5、设置 普通复选框 逻辑 二、完整代码示例1、代码示例2、执行结果 一、核心要点解析 - 表格全选复选框案例 1、案例需求 在表格中 , 设置 多…...
Lua 第6部分 函数
在 Lua 语言中,函数( Function )是对语句和表达式进行抽象的主要方式。 函数既可以用 于完成某种特定任务(有时在其他语言中也称为过程 ( procedure )或子例程 ( s ubroutine) ), 也可以只是进行…...
OpenCv高阶(五)——SIFT特征提取
目录 SIFT特征提取 一、原理核心步骤 1. 尺度空间极值检测 2. 关键点定位 3. 方向分配 4. 描述子生成 二、SIFT算法具有的特点 三、SIFT特征提取器的简单使用 1、特征检测器的创建 2、 检测图像中的关键点 3、绘制关键点 4、计算关键点描述符 四、SIFT 算法的优缺点…...
基于Spring MVC的客户端真实IP获取方案解析
文章目录 基于Spring MVC的客户端真实IP获取方案解析概述核心方法解析代码实现工作流程 IP获取优先级策略IP有效性验证异常处理与日志使用场景注意事项扩展建议 基于Spring MVC的客户端真实IP获取方案解析 概述 在Web应用开发中,准确获取客户端真实IP地址是常见的…...
JavaScript爬虫基础篇:HTTP 请求与响应
在互联网的世界里,数据无处不在。无论是新闻资讯、商品信息,还是社交媒体动态,这些数据都以各种形式存储在服务器上。而爬虫,就是我们获取这些数据的得力助手。今天,我们就来聊聊爬虫的基础——HTTP 请求与响应&#x…...
【Java基础】Java集合遍历方式
前言 在Java编程中,集合(Collection)是存储和操作对象的核心工具。遍历集合是开发者最频繁的操作之一,但不同场景下选择合适的遍历方式至关重要。 一、基础遍历方式 1. 基本for循环 适用场景:仅适用于List等有序集…...