HMAC 单向散列消息认证码

消息认证码MAC是用于确认完整性并进行认证的技术,消息认证码的输入包括任意长度的消息和一个发送者和接收者之间共享的密钥(可能还需要共享盐值)。

HMAC是使用单向散列函数来构造消息认证码的方法,任何高强度单向散列函数都可以被用于HMAC,具体方法如下图所示。

发送者需要同时把消息和认证码发送给接收者,接收者接收了两者,并根据接收到的消息和共享的密钥生成认证码进行比较。如果相同则消息未被篡改且认证成功。

MAC不能保证信息的机密性!MAC无法对第三方"C"证明,因为"A","B"两者都有密钥,都可以生成消息和MAC。因此第三方不知道是谁生成的,更不知道消息的真实性。MAC无法防止否认。

加盐

盐是通过伪随机数生成器生成的随机数,会和密钥一起被输入单向散列函数。

主要目的是为了防御字典攻击。字典攻击是一种事先进行计算并准备好候选密钥列表的方法。是一种暴力攻击破解手段。加了盐,密钥便多了n个数量级的可能,加大破解难度。

HMAC利用单向散列函数的单向性和抗碰撞性来保证无法根据MAC值推测出密钥。

代码

package main

import (
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"crypto/sha512"
"encoding/base64"
"fmt"
"hash"
"io"
) var secretKey = "114514abcdefghijklmn"
var salt = generateSalt() // 生成一个包含 16 字节数据的盐字符串
func generateSalt() string {
randomBytes := make([]byte, 16)
if _, err := rand.Read(randomBytes); err != nil {
return ""
}
return base64.URLEncoding.EncodeToString(randomBytes)
} // 提供散列函数、密钥、盐值、消息返回HMAC
func HMAC(h func() hash.Hash, secretKey string, salt string, message string) []byte {
hash := hmac.New(h, []byte(secretKey))
io.WriteString(hash, message+salt)
return hash.Sum(nil)
} func main() {
/* ----------------------------------- 发送方 ---------------------------------- */
message := "A请求B转账10000"
fmt.Println("\n\t消息: " + message)
fmt.Println("\t加盐: " + salt) fmt.Printf("\n\tHMAC-Sha256: %x", HMAC(sha256.New, secretKey, salt, message))
fmt.Printf("\n\tHMAC-Sha256: %x", HMAC(sha512.New, secretKey, salt, message)) /* ----------------------------------- 修改一个字母 ---------------------------------- */ messageChange := "C请求B转账10000" fmt.Printf("\n\n\tHMAC-Sha256: %x", HMAC(sha256.New, secretKey, salt, messageChange))
fmt.Printf("\n\tHMAC-Sha256: %x\n\n", HMAC(sha512.New, secretKey, salt, messageChange)) /* --------------------------- 接收方分别收到了发送者的消息、HMac值 -------------------------- */
// ^ 假定消息和HMAC均被黑客截获,黑客进行重放攻击
sendMessgage := message // @ 发送者发送消息
sendHMAC := string(HMAC(sha256.New, secretKey, salt, sendMessgage)) // @ 发送者计算HMAC并与消息一起发给接收者
hackerGetHMAC := sendHMAC // @ 黑客窃听到HMAC
hackerGetMessage := sendMessgage // @ 黑客窃听到消息
receiveHMAC := hackerGetHMAC // @ 接收者收到HMAC
receiveMessage := hackerGetMessage // @ 接收者收到MESSAGE
if string(HMAC(sha256.New, secretKey, salt, receiveMessage)) == receiveHMAC {
fmt.Println("\t第1次重放攻击" + message)
}
receiveHMAC = hackerGetHMAC // @ 接收者收到HMAC
receiveMessage = hackerGetMessage // @ 接收者收到MESSAGE
if string(HMAC(sha256.New, secretKey, salt, receiveMessage)) == receiveHMAC {
fmt.Println("\t第2次重放攻击" + message)
}
// ^ 假定消息和HMAC都是黑客发送的,但黑客并不知道密钥和盐值
sendMessgage = "今天是KFC V我小能喵喵喵50速速" // @ 发送者发送消息
sendHMAC = string(HMAC(sha256.New, "miyueshishenme", "114514", sendMessgage)) // @ 黑客计算HMAC并与消息一起发给接收者
receiveHMAC = sendHMAC // @ 接收者收到HMAC
receiveMessage = sendMessgage // @ 接收者收到MESSAGE
if string(HMAC(sha256.New, secretKey, salt, receiveMessage)) != receiveHMAC {
fmt.Println("\t消息不一致、认证失败")
}
}
PS C:\Users\小能喵喵喵\Desktop\Go\Cryptography\HMAC> go run .

    消息: A请求B转账10000
加盐: S_XlM8K_dhAvsgch_N3o1w== HMAC-Sha256: b8dd30d2a418262494f298bcdaf6c12f442c6e8f89a31822dad03561887f3bed
HMAC-Sha256: ba934567837ec98ba89853b09f6652ce56955cfeedd0c4495bd6cba7fc2f8293635fdc59b90180564bd0fdb1d1bffc52644fc2bd8164d6379ae11510e200954c HMAC-Sha256: 2db84d209e2418f314fc5bb0583cfb50cde90d954d8493d3ed0e3b369fb092d7
HMAC-Sha256: 7b192cedb1d89fd71889189a0094e1df06d26d977bc3bed4f53b16928aa2d58084cb8890d52cb40f665bb9ac62eeb4092495efe7d59292470ed597a3536dea56 第1次重放攻击A请求B转账10000
第2次重放攻击A请求B转账10000
消息不一致、认证失败

如何防止重放攻击

  • 给消息加序号,收发双方约定好
  • 时间戳,收发双方必须考虑到通信延迟,还是会存在重放攻击的空间。
  • 接收者发送一次性随机数,发送者HMAC该随机数后发送。确保当前消息只能发一次。

密码学奇妙之旅、03 HMAC单向散列消息认证码、Golang代码的更多相关文章

  1. 【Java-加密算法】对称加密、非对称加密、单向散列(转)

    一提到加密,就会联想到数字签名,这两个经常被混淆的概念到底是什么呢? 加密:加密是一种以密码方式发送信息的方法.只有拥有正确密钥的人才能解开这个信息的密码.对于其他人来说,这个信息看起来就像是一系列随 ...

  2. 29.密码学知识-消息认证码MAC-6——2019年12月19日

    1. 消息认证码 1.1 消息认证 消息认证码(message authentication code)是一种确认完整性并进行认证的技术,取三个单词的首字母,简称为MAC. 思考改进方案? 从哈希函数 ...

  3. 密码学初级教程(五)消息认证码MAC-Message Authentication Code

    密码学家工具箱中的6个重要的工具: 对称密码 公钥密码 单向散列函数 消息认证码 数字签名 伪随机数生成器 MAC能识别出篡改和伪装,也就是既可以确认消息的完整性,也可以进行认证. 消息认证码的输入包 ...

  4. Shiro+springboot+mybatis+EhCache(md5+salt+散列)认证与授权-03

    从上文:Shiro+springboot+mybatis(md5+salt+散列)认证与授权-02 当每次进行刷新时,都会从数据库重新查询数据进行授权操作,这样无疑给数据库造成很大的压力,所以需要引入 ...

  5. hmac库 密钥相关的哈希运算消息认证码

    # -*- coding: cp936 -*- #xiaodeng #python 2.7.10 #HMAC是密钥相关的哈希运算消息认证码,HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一 ...

  6. HMAC哈希消息认证码

    收藏 137 14   hmac 编辑 HMAC是密钥相关的哈希运算消息认证码,HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出.   中文名 哈希消息认证码 外文名 H ...

  7. Shiro+springboot+mybatis(md5+salt+散列)认证与授权-02

    代码延续地址:Shiro+springboot+mybatis(md5+salt+散列)认证与授权-01 1.创建t_role角色表(比如管理员admin,普通用户user等),创建t_pers权限表 ...

  8. 密码学奇妙之旅、02 混合加密系统、AES、RSA标准、Golang代码

    CTR 计数器模式 计数器模式CTR是分组密码模式中的一种.通过将逐次累加的计数器进行加密来生成密钥流的流密码.每次加密时会生成一个不同的值来作为计数器的初始值. 可以事先进行加密.解密的准备. 加密 ...

  9. Shiro+springboot+mybatis(md5+salt+散列)认证与授权-01

    这个小项目包含了注册与登录,使用了springboot+mybatis+shiro的技术栈:当用户在浏览器登录时发起请求时,首先这一系列的请求会被拦截器进行拦截(ShiroFilter),然后拦截器根 ...

随机推荐

  1. 聊聊 C++ 右值引用 和 移动构造函数

    一: 背景 最近在看 C++ 的右值引用和移动构造函数,感觉这东西一时半会还挺难理解的,可能是没踩过这方面的坑,所以没有那么大的深有体会,不管怎么说,这一篇我试着聊一下. 二: 右值引用 1. 它到底 ...

  2. salt stack学习笔记

    saltstack运行模式: local master/minion salt ssh saltstack三大功能 远程执行命令 配置管理(状态管理) 云管理 安装: master  salt-mas ...

  3. Linux—文件系统结构

    1.文件目录结构 /:是Linux系统的根目录 /bin:存放用户经常使用的命令 /boot:启动加载程序的静态文件 /dev:设备文件目录,不能单独分区 /etc:系统配置文件目录 /home:普通 ...

  4. SpringBoot 如何集成 MyBatisPlus - SpringBoot 2.7.2实战基础

    SpringBoot 2.7.2 学习系列,本节通过实战内容讲解如何集成 MyBatisPlus 本文在前文的基础上集成 MyBatisPlus,并创建数据库表,实现一个实体简单的 CRUD 接口. ...

  5. 2022了你还不会『低代码』?数据科学也能玩转Low-Code啦! ⛵

    作者:韩信子@ShowMeAI 数据分析实战系列:http://www.showmeai.tech/tutorials/40 机器学习实战系列:http://www.showmeai.tech/tut ...

  6. 技术分享 | 浅谈mysql语法解析调试方法

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 本文向您介绍一种利用mysql解析器和bison的调试选项进行sql语法解析跟踪 ...

  7. CF280D k-Maximum Subsequence Sum(线段树)

    在做这题时我一开始把\(tag\)写入了结构体 #include <iostream> #include <cstdio> #include <cstring> # ...

  8. TS 泛型推断好难啊,看看你能写出来不

    前言 最近做东西都在用ts,有时候写比较复杂的功能,如果不熟悉,类型写起来还是挺麻烦的.有这样一个功能,在这里,我们就不以我们现有的业务来举例了,我们还是已Animal举例,来说明场景.通过一个工厂来 ...

  9. jQuery 判断父节点下是否有子节点

    查找父节点下是否有子节点有两个情况:(1)查找的是父元素的所有后代节点:(2)仅查找父元素的第一代子节点. <div id="app"> <div> < ...

  10. 四连测总结(XYX)

    目录 成绩 总结 事后... 成绩 telephonewire monkey 总分 0 56 56 cowjog guard path temperature 总分 0 40 0 68 108 cba ...