HMAC 详解:在 Golang 中实现消息认证码
目录
什么是 HMAC
HMAC 的主要用途
HMAC 的工作原理
Golang 中的 crypto/hmac 包
如何选择合适的哈希函数和密钥长度
小结
什么是 HMAC
HMAC(Hash-based Message Authentication Code)是一种基于 Hash 函数和密钥的消息认证码,由 H.Krawezyk,M.Bellare,R.Canetti 于1996年提出的一种基于 Hash 函数和密钥进行消息认证的方法,并于1997年作为 RFC2104 被公布。HMAC 将密钥、消息和哈希函数一起使用,确保消息在传输过程中不被篡改,还可以验证消息的发送者身份。
HMAC 的主要用途
HMAC 主要用于以下几个方面:
- 校验数据的完整性:HMAC可以用于校验数据在传输过程中是否被篡改,接收者通过计算接收到的消息的 HMAC,与接收到的 HMAC 进行比较,如果相同的话,可以认为数据是完整的。
- 用于身份验证:HMAC 还可以用于验证消息的发送者。因为 HMAC 的计算需要一个密钥,只有知道这个密钥的人才能生成正确的 HMAC。所以,如果一个消息的 HMAC 是正确的,可以认为这个消息确实来自声称的发送者,典型的使用场景是 OpenAPI。
- 防止重放攻击:在某些情况下,HMAC 还可用于防重放攻击。在消息中添加一个时间戳或序列号,并参与 HMAC 的计算,接收者可以拒绝那些具有旧时间戳或序列号的消息,从而防止攻击者重放旧消息。
- 安全协议:HMAC 在很多安全协议中都有应用,例如 IPSec(用于保护 Internet Protocol 通信)和 TLS(用于保护 Web 通信)。这些协议使用 HMAC 来确保数据的完整性和验证发送者的身份。
HMAC 的工作原理
HMAC 的典型使用方式如下:
- 确定一个哈希函数(如 SHA256 或 MD5)和一个密钥。
- 通过将密钥和消息组合,并通过哈希函数运算,生成固定大小的数据(称为消息认证码)。
- 当消息接收者收到消息和 HMAC 时,使用同样的密钥和哈希函数对接收到的消息进行运算,然后将结果与接收到的 HMAC 进行比较,如果相同,消息就被认为是完整的且未被篡改,并且确实来自声称的发送者。
Golang 中的 crypto/hmac 包
Golang 中的 crypto/hmac 包提供了 HMAC 的实现方法。以下是 crypto/hmac 包的一些主要函数和用法:
- New 函数,接收一个哈希函数和一个密钥,返回一个用来计算 HMAC 的 hash.Hash。
h := hmac.New(sha256.New, key)
- Write 方法,可以向 HMAC 添加数据,实现了 io.Writer 接口。
_, err := h.Write(data)
if err != nil {log.Fatal(err)
}
- Sum 方法,返回当前的哈希值作为字节切片。可以选择提供一个已存在的字节切片,哈希值会被追加到这个切片的末尾。
result := h.Sum(nil)
- Equal 函数,用于比较两个 HMAC 是否相等,这个函数可以防止 timing attack 类型的攻击(使用相同的时间来进行比较)。
isValid := hmac.Equal(mac1, mac2)
可以看出Equal函数并不是简单地使用`==`运算符来比较两个 HMAC 值,而是使用了一种叫做"constant time comparison"的技术来做比较。这种技术可以确保比较花费的时间不依赖比较的数据,从而防止 timing attack 类型的攻击。攻击者通过计算比较操作花费的时间,可以推断出一些关于数据的信息。例如,如果比较操作花费的时间和字节数有某种关系,攻击者就可以通过改变输入,观察比较操作花费时间的变化,从而推断出正确的 HMAC 值。
以下是一个使用 crypto/hmac 包生成 HMAC 的例子,代码如下:
package mainimport ("crypto/hmac""crypto/sha256""fmt"
)func main() {key := []byte("secret key")data := []byte("message to authenticate")h := hmac.New(sha256.New, key)_, err := h.Write(data)if err != nil {fmt.Println("Error writing to HMAC:", err)return}result := h.Sum(nil)fmt.Printf("HMAC: %x\n", result)
}
这个例子是使用 SHA-256 作为底层的哈希函数,但也可以使用任何实现了 hash.Hash 接口的哈希函数。
如何选择合适的哈希函数和密钥长度
选择 HMAC 的哈希函数和密钥长度时,需要考虑以下几个因素:
- 安全需求:安全需求是决定哈希函数和密钥长度选择的最重要因素。如果需要更高的安全性,应该选择更强大的哈希函数和更长的密钥。例如,SHA-256 或 SHA-3。
- 性能需求:更强大的哈希函数和更长的密钥通常会更耗性能。如果系统对性能有严格的要求,可能需要在安全性和性能之间做出权衡。
- 兼容性:如果系统需要与其他系统交互,可能需要选择一个与其他系统兼容的哈希函数和密钥长度。
关于哈希函数,应该选择一个被广泛接受并且经过了严格安全检验的哈希函数。SHA-256 是被广泛接受的一种哈希算法,不仅提供了足够的安全性,并且在大多数现代硬件上都有很好的性能。
关于密钥长度,一般来说,密钥的长度应该至少与哈希函数的输出长度相同。例如,如果使用了 SHA-256,那么密钥长度应该至少为256位。如果密钥太短,可能会降低 HMAC的安全性。如果密钥太长,浪费服务器资源不说,也不会进一步提高 HMAC 的安全性。所以,选择一个与哈希函数输出长度相同的密钥长度是一个好的选择。
小结
本文详细讲解了如何在 Golang 中实现 HMAC,首先介绍了 HMAC 的基本概念和用途。然后详细讲解了 HMAC 的工作原理,包括如何选择哈希函数和密钥。希望能帮助你理解和有效使用 HMAC 来提高程序的全性。
相关文章:
HMAC 详解:在 Golang 中实现消息认证码
目录 什么是 HMAC HMAC 的主要用途 HMAC 的工作原理 Golang 中的 crypto/hmac 包 如何选择合适的哈希函数和密钥长度 小结 什么是 HMAC HMAC(Hash-based Message Authentication Code)是一种基于 Hash 函数和密钥的消息认证码,由 H.Kr…...
阻塞队列和定时器的使用
阻塞队列 谈到队列,大家就能想到队列的先进先出原则,但有些特殊的队列,虽然也是先进先出的,但是带有阻塞功能,我们把这种队列叫做阻塞队列. ★如果队列为空,执行出队操作就会阻塞,阻塞到另外一个线程往队列里添加元素(队列不为空)为止. ★如果队列满了,执行入队操作时,也会阻…...
JavaScript脚本操作CSS
脚本化CSS就是使用JavaScript脚本操作CSS,配合HTML5、Ajax、jQuery等技术,可以设计出细腻、逼真的页面特效和交互行为,提升用户体验,如网页对象的显示/隐藏、定位、变形、运动等动态样式。 1、CSS脚本化基础 CSS样式有两种形式&…...
Rust4.1 Managing Growing Projects with Packages, Crates, and Modules
Rust学习笔记 Rust编程语言入门教程课程笔记 参考教材: The Rust Programming Language (by Steve Klabnik and Carol Nichols, with contributions from the Rust Community) Lecture 7: Managing Growing Projects with Packages, Crates, and Modules src/main.rs // s…...
RPA在财务预测和分析中的应用
在现代企业管理中,财务数据分析是决策制定和战略规划的关键环节。大数据的兴起带来财务数据的复杂性和数量不断增加,企业为此消耗了大量人力和物力。随着当今数字化、智能化时代的到来,越来越多企业引进RPA技术来提高工作效率,实现…...
无人机航拍技术基础入门,无人机拍摄的方法与技巧
一、教程描述 买了无人机,可是我不敢飞怎么办?禁飞区越来越多,到底哪儿才能飞?我的无人机跟你一样,为什么我拍不出大片?厂家的说明书看不进去,有没有一套无人机的课程,可以快速上手…...
PTA 哈密尔回路(建图搜索)
题目 著名的“汉密尔顿(Hamilton)回路问题”是要找一个能遍历图中所有顶点的简单回路(即每个顶点只访问 1 次)。本题就要求你判断任一给定的回路是否汉密尔顿回路。 输入格式: 首先第一行给出两个正整数:…...
如何利用产品帮助中心提升用户体验
在当今竞争激烈的市场中,提供优秀的用户体验是吸引和保留客户的关键。而一个高效和易于使用的产品帮助中心,正成为越来越多企业用以提升用户体验的重要工具。产品帮助中心是一个集中的信息库,为用户提供关于产品功能、故障排除、常见问题解答…...
【Python大数据笔记_day05_Hive基础操作】
一.SQL,Hive和MapReduce的关系 用户在hive上编写sql语句,hive把sql语句转化为MapReduce程序去执行 二.Hive架构映射流程 用户接口: 包括CLI、JDBC/ODBC、WebGUI,CLI(command line interface)为shell命令行;Hive中的Thrift服务器允许外部客户端…...
css呼吸效果实现
实现一个图片有规律的大小变化,呈现呼吸效果,怎么用CSS实现这个呼吸效果呢 一.实现 CSS实现动态效果可以使用动画( animation)来属性实现,放大缩小效果可以用transform: scale来实现,在这基础上有了动画,就可以设置一个…...
机器视觉opencv答题卡识别系统 计算机竞赛
0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 答题卡识别系统 - opencv python 图像识别 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分…...
2024年的后端和Web开发趋势
目录 1 2 3 4 5 1 不断变化的数字创新格局可能让人感觉像是一场无情的竞赛。作为开发人员,你的痛苦是真实的——交付尖端产品、保持竞争力、跟上不断变化的用户期望,综合起来你的压力可能是压倒性的。 但是,如果我们告诉你有一个指南针…...
对比了10+网盘资源搜索工具,我最终选择了这款爆赞的阿里云盘、百度网盘、夸克网盘资源一站式搜索工具
盘友圈(https://panyq.com)是一个综合性的网盘搜索站,与其他网盘搜索工具相比,它具有多个独特的优点,使其成为用户们首选的平台。 首先,盘友圈汇集了阿里云盘、百度网盘和夸克网盘等主流网盘资源ÿ…...
GoLong的学习之路(二十)进阶,语法之反射(reflect包)
这个是为了接上之前的语法篇的。按照我的学习计划,这里此时应该有一个小项目来做一个统合。但是吧,突然觉得,似乎也没必要。能学go的大部分肯定都是有其他语言的基础的。 接下来说反射 文章目录 反射介绍reflect包TypeOftype name和type kin…...
关于表单校验,:rules=“loginRules“
在写好validator相关的方法后,rule测试没有生效 <el-form ref"loginForm" :model"loginForm" :rules"loginRules" class"login-form" <el-form-item prop"username"> <el-input ref"usernam…...
统一消息分发中心设计
背景 我们核心业务中订单完成时,需要完成后续的连带业务,扣件库存库存、增加积分、通知商家等。 如下图的架构: 这样设计出来导致我们的核心业务和其他业务耦合,每次新增连带业务或者去掉连带业务都需要修改核心业务。 一方面&…...
前端项目导入vue和element
1.安装nodejs 下载链接https://cdn.npmmirror.com/binaries/node/v18.18.0/node-v18.18.0-x64.msi 进入cmd 命令行模式 管理员身份运行 输入 (node -v)能看到版本号 npm config set prefix "C:\Program Files\nodejs" 默认路径 npm config…...
【11】使用透视投影建立一个3D空间的测试
核心操作: 1.proj view model 这三个矩阵 glm::mat4 mvp m_Proj * m_View * model; m_Shader->Bind(); m_Shader->SetUniformMat4f("u_MVP", mvp);着色器里面就: proj:投影矩阵,可以选择正交投影,或者透视投影…...
【广州华锐互动】VR影视制片虚拟仿真教学系统
随着虚拟现实(VR)技术的不断发展,VR在影视制片教学中的应用场景也变得越来越丰富。本文将介绍VR在影视制片教学中的常见应用场景及其意义,并通过案例分析来更好地展示其应用前景。 在影视制片教学中,VR可以提供一种沉浸式的制作体验。其中&am…...
从研发域到量产域的自动驾驶工具链探索与实践
导读 本文整理自 2023 年 9 月 5 日百度云智大会 - 智能汽车分论坛,百度智能云自动驾驶云研发高级经理徐鹏的主题演讲《从研发域到量产域的自动驾驶工具链探索与实践》。 全文中部段落附有演讲中 2 个产品演示视频的完整版,精彩不容错过。 (视频观看&…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
怎么开发一个网络协议模块(C语言框架)之(六) ——通用对象池总结(核心)
+---------------------------+ | operEntryTbl[] | ← 操作对象池 (对象数组) +---------------------------+ | 0 | 1 | 2 | ... | N-1 | +---------------------------+↓ 初始化时全部加入 +------------------------+ +-------------------------+ | …...
数据库——redis
一、Redis 介绍 1. 概述 Redis(Remote Dictionary Server)是一个开源的、高性能的内存键值数据库系统,具有以下核心特点: 内存存储架构:数据主要存储在内存中,提供微秒级的读写响应 多数据结构支持&…...
鸿蒙Navigation路由导航-基本使用介绍
1. Navigation介绍 Navigation组件是路由导航的根视图容器,一般作为Page页面的根容器使用,其内部默认包含了标题栏、内容区和工具栏,其中内容区默认首页显示导航内容(Navigation的子组件)或非首页显示(Nav…...
