openssl做HMAC实例(C++)

2023-11-06

1、HMAC简介

1MAC(Message Authentication Code,消息认证码算法),可以将其认为是含有秘钥的散列(Hash)函数算法;即兼容了MDSHA算法,并在此基础上加上了秘钥。因此MAC算法也经常被称作HMAC算法。当然HMAC就是“基于Hash的消息认证码”英文(Hash-based Message Authentication Code)的缩写。我个人理解它主要包括两块:一个是信息摘要算法(MD/SHA);另外就是秘钥。

    1HMAC基于的信息摘要算法。目前主要集合了MD和SHA两大系列消息摘要算法。其中MD系列的算法有HmacMD2、HmacMD4、HmacMD5三种算法;SHA系列的算法有HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512五种算法。

    2)秘钥。理论上密钥可以是任何长度,但是一般出于安全强度的考量不建议使用太短的秘钥。也就是说一般情况下要使用摘要算法计算密钥的摘要作为新的密钥。

2)使用流程。你和对方共享了一个密钥K,你要发消息给对方;这个过程即要保证消息没有被篡改还要能够证明信息确实是你本人发送的。所以处理的方式是:在发送数据以前,HMAC算法对数据块+约定的公钥进行散列操作并将所生成摘要”附加在待发送的数据块中。当数据和摘要到达其目的地时,目的端也会使用HMAC算法对原数据块和公钥来生成本地摘要,如果两个摘要相匹配,那么就认为数据未被做任何篡改且消息为约定的对方本人发送

(3)加深理解。

1)其实通过MD5、SHA1等哈希算法我们可以验证一段数据是否有效,方法就是对比该数据的哈希值。例如判断用户的口令(密码)是否正确我们用保存在数据库中的password_md5对比计算得到的md5(password),如果一致就认为用户输入的密码是正确的。

2)由于用户密码通常会设置的比较简单而且具有普遍性,如果黑客做了足够大的对照表实际上就很有可能反推出真实密码。为了防止黑客通过对照表反推到原始密码,通常在计算哈希的时候会增加一个salt以使得相同的输入(这里指不同用户的相同密码)也能达到不同的哈希(例如将每个用户的唯一id作为salt的一部分),这样就大大的增加了破解难度。

3)实际上我们可以把上面说的salt看做是一个“口令”,所以加salt的哈希就是:计算一段message的哈希时,根据不同的口令计算出不同的哈希。即,要验证哈希值必须同时提供口令。上面的这个思路实际上就是Hmac算法了,它通过一个标准算法,在计算哈希的过程中把key混入计算过程。和我们自定义的加salt算法不同,Hmac算法针对所有的哈希算法都通用,无论是MD5还是SHA-1。其实可以认为Hmac算法和我们自定义的加salt的哈希算法本质上就是一个东西。但是使用Hmac替代我们自己的salt算法可以使程序算法更标准话,也更安全

2、实例程序(打包代码 这里 )

(1)algo_hmac.h

#ifndef _ALGO_HMAC_H_
#define _ALGO_HMAC_H_

int HmacEncode(const char * algo,
	const char * key, unsigned int key_length,
	const char * input, unsigned int input_length,
	unsigned char * &output, unsigned int &output_length);

#endif

(2)algo_hmac.cpp

#include "algo_hmac.h"
#include <openssl/hmac.h>
#include <string.h>
#include <iostream>
using namespace std;

int HmacEncode(const char * algo, 
		const char * key, unsigned int key_length, 
		const char * input, unsigned int input_length, 
		unsigned char * &output, unsigned int &output_length) {
	const EVP_MD * engine = NULL;
	if(strcasecmp("sha512", algo) == 0) {
		engine = EVP_sha512();
	}
	else if(strcasecmp("sha256", algo) == 0) {
		engine = EVP_sha256();
	}
	else if(strcasecmp("sha1", algo) == 0) {
		engine = EVP_sha1();
	}
	else if(strcasecmp("md5", algo) == 0) {
		engine = EVP_md5();
	}
	else if(strcasecmp("sha224", algo) == 0) {
		engine = EVP_sha224();
	}
	else if(strcasecmp("sha384", algo) == 0) {
		engine = EVP_sha384();
	}
	else if(strcasecmp("sha", algo) == 0) {
		engine = EVP_sha();
	}
	else if(strcasecmp("md2", algo) == 0) {
		engine = EVP_md2();
	}
	else {
		cout << "Algorithm " << algo << " is not supported by this program!" << endl;
		return -1;
	}

	output = (unsigned char*)malloc(EVP_MAX_MD_SIZE);
	/*---------------------------------
	这块应该是相对通用的计算流程了
	--------------------------------*/
	HMAC_CTX ctx;
	HMAC_CTX_init(&ctx);
	HMAC_Init_ex(&ctx, key, strlen(key), engine, NULL);
	HMAC_Update(&ctx, (unsigned char*)input, strlen(input));	// input is OK; &input is WRONG !!!

	HMAC_Final(&ctx, output, &output_length);
	HMAC_CTX_cleanup(&ctx);	

	return 0;
}

(3)main.cpp

#include "algo_hmac.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;

int main(int argc, char * argv[])
{
	if(argc < 2) {
		//参数指定hash算法,支持HmacEncode列举的那些
		cout << "Please specify a hash algorithm!" << endl;
		return -1;
	}

	char key[] = "fasdkgjl;asdfjg;dsfjgasdsr";//secret key
	string data = "/pic/small/3007024147/8ba5a744-f48d-4ba2-b93f-da17e7f52dff";//要加密传输的数据

	unsigned char * mac = NULL;
	unsigned int mac_length = 0;
	
	int ret = HmacEncode(argv[1], key, strlen(key), data.c_str(), data.length(), mac, mac_length);	
	
	if(0 == ret) {
		cout << "Algorithm HMAC encode succeeded!" << endl;
	}
	else {
		cout << "Algorithm HMAC encode failed!" << endl;
		return -1;
	}

	cout << "mac length: " << mac_length << endl;
	cout << "mac:";
	for(int i = 0; i < mac_length; i++) {
		printf("%-03x", (unsigned int)mac[i]);
	}
	cout << endl;
	
	if(mac) {
		free(mac);
		cout << "mac is freed!" << endl;
	}

	return 0;
}

(4)Makefile

LNK_OPT = -g -L/usr/lib64/ -lssl  -L/lib64/ -lcrypto

all:
	rm -f *.o
	rm -f test
	g++ -g -c algo_hmac.cpp
	g++ -g main.cpp -o test algo_hmac.o $(LNK_OPT)

clean:
	rm -f *.o
	rm -f test

3、执行效果

执行效果如下:

各种算法得到的摘要长度如下:

算法 摘要长度(字节)
MD2 16
MD5 16
SHA 20
SHA1 20
SHA224 28
SHA256 32
SHA384 48
SHA512 64

参考:用OpenSSL 做HMAC(C++)_yasi_xi的博客-CSDN博客_openssl/hmac.h

4、HMAC相关函数

官网   /docs/man1.0.2/man3/HMAC_CTX_cleanup.html

主要涉及如下函数:

HMAC, HMAC_CTX_init, HMAC_Init, HMAC_Init_ex, HMAC_Update, HMAC_Final, HMAC_CTX_cleanup, HMAC_cleanup - HMAC message authentication code

注:其中 HMAC_CTX_cleanup 作用如下。如果结尾处不调用此函数的话会导致内存泄漏。

HMAC_CTX_cleanup() erases the key and other data from the HMAC_CTX and releases any associated resources. It must be called when an HMAC_CTX is no longer required.

关于遗漏 HMAC_CTX_cleanup 引发的内存泄漏的实际测试可以参照这篇文章。

https://blog.csdn.net/mijichui2153/article/details/126412532?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22126412532%22%2C%22source%22%3A%22mijichui2153%22%7D

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

openssl做HMAC实例(C++) 的相关文章

  • AES的256位密钥加解密报 java.security.InvalidKeyException: Illegal key size or default parameters 异常的处理及处理工具

    在做第三方对接进行AES加密 256位 的时候遇到的错误 这哥们写的非常详细 转载地址 https blog csdn net dafeige8 article details 76019911 一 出现的现象 为了数据代码在传输过程中的安
  • protobuf介绍和语法

    目录 前言 语法 标识符 字段 字段类型 proto2和proto3区别 前言 Protobuf即Protocol Buffers 是Google公司开发的一种跨语言和平台的序列化数据结构的方式 是一个灵活的 高效的用于序列化数据的协议 与
  • 代码混淆不一定要花大价钱,Code Virtualizer也能轻松搞定!

    任何创建创新性应用程序 DLL或设备驱动程序的开发人员都希望将代码尽可能机密 以避免第三方公司 开发人员研究应用程序内的代码并为自己的利益而窃取代码 一些开发人员使用外部保护系统来打包应用程序并保护其免受攻击者的侵害 但是大多数时候 这些保
  • python写几种base加解密

    源代码 import base64 def b64encode basec PlainText basec encode utf 8 a base64 b64encode PlainText CipherText a decode utf
  • 前后端RSA加解密

    前端vue RSA加密 一 安装 npm install jsencrypt save dev 二 创建js文件 在src目录下创建util文件夹 然后在util文件夹下创建 security js 文件 1 引入jsencrypt 引入加
  • nodejs的加密方式

    nodejs的加密方式 一 加密算法 为了保证数据的安全性和防篡改 很多数据在传输中都进行了加密 加密可分为三大类 对称加密 非对称加密 摘要算法 二 对称加密 采用单钥密码系统的加密方法 同一个密钥可以同时作用信息的加密和解密 该方法称为
  • http协议详解

    本篇博文主要介绍HTTP请求 响应的系列过程 包括四个部分 是在陆续学习中觉着之间有关联总结下来的 以便自己今后忘记后可以快速查看也为各位看到这篇文章的朋友们梳理一下知识 下面 正文开始 作为一个前端开发人员 我们每天都在与页面打交道 那么
  • js加密字符串

    字符串加密 用javascript对字符串进行加密 应用于参数传递等 默认加密密钥为kb1234 使用者可自定义修改 注意加密密钥应和解密密钥相同 算法来自于互联网 使用方法 加密 var code kbt encrypt 我爱北京天安门
  • python代码使用cython进行加密

    python代码加密 前言 加密的多种方式 Cython加密 步骤 注意 部署 前言 加密的多种方式 发布编译过的pyc文件 缺点 很容易被反编译 PyInstaller 是一个用来将 Python 程序打包成一个独立可执行软件包 支持 W
  • IEC104协议的参数设置

    本文主要是IEC104协议的参数的定义及个人的理解 如有错误请指正 重要参数 104规约规定了两个参数K和W 其取值为1到32767 其中K表示发送方在有K个I格式报文未得到对方的确认时 将停止数据发送 W表示接收方最迟在接收W个I格式报文
  • verilog_串口实现

    verilog 串口实现 概述 先了解串口的基础知识 串口是怎样传数据的 什么是波特率 波特率怎么计算 说明 通过Verilog编写串口 通过逻辑分析仪与串口模块的对接来进一步了解串口的应用 文章目录 1 什么是波特率 波特率怎么计算 1
  • Https 公钥私钥交换过程

    记录一下Https 公钥私钥加密过程 对称加密 编 解码使用相同密钥的算法 一般是共享密钥 非对称加密 非对称加密算法需要两个密钥 公开密钥 publickey 简称公钥 和私有密钥 privatekey 简称私钥 公钥与私钥是一对 如果用
  • Zmodem协议由浅入深

    Zmodem协议由浅入深 废话不多说直接解释 1 最简单的 ZMODEM 文件传输显示如下 例如 发送器要发送 爸爸的爸爸到底叫什么呀丫鸭压 gt gt gt gt gt 给接收器 逻辑如下 发送器 问 接收器可以接受什么类型的数据 接受器
  • kafka简介和使用

    1 kafka介绍 1 1 主要功能 根据官网的介绍 ApacheKafka 是一个分布式流媒体平台 它主要有3种功能 1 It lets you publish and subscribe to streams of records 发布
  • 非对称加密工作原理

    非对称加密 非对称加密使用两个密钥 一个是public key 一个是private key 通过某个算法 使得数据的加密和解密使用不同的密钥 因为用的是不同的密钥 所以称为非对称加密 非对称加密最著名的是RSA算法 这是以其发明者Rive
  • UDP用户数据报协议分析

    简介 UDP User Datagram Protocol 即用户数据报协议 在网络中它与TCP协议一样用于处理数据包 是一种无连接的协议 在OSI模型中 在第四层 传输层 处于IP协议的上一层 UDP用来支持那些需要在计算机之间传输数据的
  • PPPoE协议详解

    PPPoE协议详解 PPPoE协议的工作流程包含发现和会话两个阶段 发现阶段是无状态的 目的是获得PPPoE终结端 在局端的ADSL设备上 的以太网MAC地址 并建立一个惟一的PPPoESESSION ID 发现阶段结束后 就进入标准的PP
  • Unity手游资源修改流程

    最近接到一个Android手游汉化需求 研究了一下 特此记录 开发环境 AssetStudioGUI 该软件可解析 定位压缩后的Unity 资源 下载 https github com Perfare AssetStudio AssetBu
  • DNS使用TCP与UDP

    DNS同时占用UDP和TCP端口53是公认的 这种单个应用协议同时使用两种传输协议的情况在TCP IP栈也算是个另类 但很少有人知道DNS分别在什么情况下使用这两种协议 先简单介绍下TCP与UDP TCP是一种面向连接的协议 提供可靠的数据
  • 协议茶馆:TLV 格式及编码

    本篇是多年前的存篇 出处不详 旧酒换新瓶 温故知新 有了新的理解 一 什么是 TLV 格式 几乎所有的通信都有协议 而几乎所有的需要在卡片和终端之间传送的数据 结构 都是 TLV 格式的 TLV 是 tag length 和 value 的

随机推荐

  • 少儿机器人编程有什么用

    少儿机器人编程有什么用 小孩的学习一直以来都是家长们非常关心和重视的一件事情 很多的家长在培养孩子的学习方面也可以说是相当的耐心的 会给孩子选择一些能更有利于孩子成长的课程 就拿现在很多的家长想要孩子去学习机器人编程的课程来说 有的家长对于
  • 解决Enter passphrase for key

    两种解决方案 提示 Permissions 0644 for ssh id rsa pub are too open 解决方法 使用chmod 0600 ssh id rsa pub更改将公钥权限改成 600 提示 Enter passph
  • Java中的静态变量&静态方法

    静态变量 静态方法 静态变量又叫做类变量 静态方法又被称为类方法 均被static修饰 未被static修饰的成员变量和方法分别被称为实例变量和实例方法 1 静态方法中不需要它所属类的任何实例就可以访问 所以在静态方法中不可以使用this关
  • Swift语法学习--运算符与流程控制

    文章目录 运算符 循环 条件 预处理器指令 运算符 普通的运算符加减乘除 与或非 三元运算我觉得没必要再赘述了 就记录一下我不熟悉的 循环 条件 预处理器指令
  • SQL Server 数据库中添加文件组和数据文件

    SQL Server 现有数据库中添加文件组和数据文件 use CURRENT DB 进入当前操作数据库 go alter database CURRENT DB add filegroup FG1 向CURRENT DB 数据库添加FG1
  • idea安装插件plugin(主要针对网络连接不上的情况)

    STEP1 ctrl alt s 打开settings STEP2 在输入框键入 Plugins STEP3 输入你想要的插件名称 我这边输入的是nodejs 因为最近在学 我这边是安装过的 所以这样显示 STEP4 点开中下方的前两个按钮
  • 在windows下编译glib库

    glib库是跨平台的C语言函数库 是Gtk 库和Gnome的基础 glib可以在多个平台下使用 比如Linux Unix Windows等 glib为许多标准的 常用的C语言结构提供了相应的替代物 先从官网下载下载 https downlo
  • Linux网络通信总结

    网络IO之阻塞 非阻塞 同步 异步 单播 多播 组播 广播 多路复用POLL SELECT epoll 超时 read write accept connect 超时 实现 1 用select来设置超时机制 2 使用setsockopt 函
  • React 子向父级组件通信时,state为旧的数据

    问题描述 当嵌套太深的子组件触发更新父组件时 父组件获取到的state map传入子组件 是旧的 问题场景 初始子组件仅为1个Input输入框 新增后有2个Input输入框 此时触发222输入框的修改 通知上级组件保存修改的内容时 父组件存
  • 数据结构—单链表C语言刷题2

    目录 1 链表分割 2 链表的回文结构 3 相交链表 4 环形链表 5 环形链表II 1 链表分割 题目链接 链表分割 题目描述 现有一链表的头指针 ListNode pHead 给一定值x 编写一段代码将所有小于x的结点排在其余结点之前
  • Debug下出现debug assertion failed

    出现debug assertion failed界面后点击重试跳到这句ASSERT m hObject NULL 采用注释查找错误的方式定位至 if CFrameWnd OnCreate lpCreateStruct 1 return 1
  • 获取referer中的请求参数_Http请求头中的referer

    Referer是 HTTP请求header 的一部分 当浏览器 或者模拟浏览器行为 向web 服务器发送请求的时候 头信息里有包含 Referer 比如我在www google com 里有一个www baidu com 链接 那么点击这个
  • 在Linux内核中添加自己的驱动程序

    就说一下怎么添加进去吧 首先你要把驱动程序写好 我已添加 首先在drivers目录下面创建GPIO文件夹 文件夹下面创建三个文件 分别是 gpio c Kconfig Makefile 三个文件 gpio c是你的驱动程序 Kconfig是
  • Spring复习笔记

    1 Spring 1 1 简介 优点 Spring是一个轻量级控制反转 IoC 和面向切面 AOP 的容器 轻量级 低侵入 松耦合 框架粘合剂 更容易整合其他框架 支持事务处理 官网 https spring io projects spr
  • 不怕死就上这些网站

    1 hxxp www dj3344 com 打开后 重启时你的主页就变成它的 并通过QQ向他人传播 现在正飙行 奇坏无比 2 hxxp www qq168 net 打开后 重启时你的主页就变成它的 并通过QQ向他人传播 而且传波病毒 还狠些
  • 我的GIT练习Four

    目录 前言 GIT安装教程 Git作者 GIT优点 GIT缺点 为什么要使用 Git GIT练习Four C1 初始化项目 C2 设计项目首页 C3 设计登录页面 C4 实现登录功能 C5 设计后台页面 C6 设计注册页面 C7 实现注册功
  • 拼搏百天!上月喜获阿里内推,交叉面把面试官面傻眼了

    阿里内推一面 项目 1 面试官让我描述一个自己印象最深的项目 手画设计图 2 针对项目中的技术进行发问 比如 架构设计 部署图 模块之间的通信等 3 因为我描述项目存储数据比较多 让我重新设计数据库的表 怎么设计 后面都是针对项目技术的问题
  • iOS 蓝牙扫描枪扫描内容不正确

    背景 在移动设备上 使用蓝牙扫描枪 相当于接入了一下外接键盘 我们的客户使用我们的App 并连接蓝牙扫码枪 将扫描的内容传输到我们的App中 App再做出对应的响应 举个例子 较为常见的应用场景就是 拣货员拿着扫码枪 扫描产品上的UPC码
  • HttpClient的ssl方式发送请求

    最近因为项目需要 需要以rest方式和第三方平台交互 由于需要ssl方式连接 所以记录一下 maven依赖如下
  • openssl做HMAC实例(C++)

    1 HMAC简介 1 MAC Message Authentication Code 消息认证码算法 可以将其认为是含有秘钥的散列 Hash 函数算法 即兼容了MD和SHA算法 并在此基础上加上了秘钥 因此MAC算法也经常被称作HMAC算法