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

hmac — 加密消息签名和验证

hmac — 加密消息签名和验证

1.概述

它的全称叫做Hash-based Message Authentication Code: 哈希消息认证码,从名字中就可以看出来这个hmac基于哈希函数的,并且还得提供一个秘钥key,它的作用就是用来保证消息的完整性,不可篡改。基本思想就是,将消息用一个哈希函数加上一个秘钥key生成一个摘要,比如现在很流行的JWT就是基于hmac实现的。

2.签名消息

2.1.默认MD5算法加密

new() 函数创建一个用于计算消息签名的新对象。此示例使用默认的 MD5 散列算法。

import hmacdigest_maker = hmac.new(b'secret-shared-key-goes-here')with open('lorem.txt', 'rb') as f:while True:block = f.read(1024)if not block:breakdigest_maker.update(block)digest = digest_maker.hexdigest()
print(digest)

运行时,代码读取数据文件并为其计算 HMAC 签名

4bcb287e284f8c21e87e14ba2dc40b16

2.2.可选算法加密

尽管默认的 hmac 算法是 MD5,但那不是最安全的方法。MD5 摘要算法有一些缺点,例如碰撞?(两个不同的消息产生了不同的哈希值)。 SHA-1 被公认为是比较健壮的,应该使用它。

import hmac
import hashlibdigest_maker = hmac.new(b'secret-shared-key-goes-here',b'',hashlib.sha1,
)with open('hmac_sha.py', 'rb') as f:while True:block = f.read(1024)if not block:breakdigest_maker.update(block)digest = digest_maker.hexdigest()
print(digest)

new() 函数接受三个参数值,第一个是密钥,共享于两个通信的端点之间,所以两个端点都使用相同的值。第二个参数是初始化消息值。如果需要认证的消息内容非常小,例如时间戳或者 HTTP POST,那么整个消息体可以传入 new() 而不用 update() 方法。最后一个参数是要使用的摘要算法。默认的是 hashlib.md5,例子中使用的是 hashlib.sha1。

dcee20eeee9ef8a453453f510d9b6765921cf099

2.3.二进制摘要

前一个例子使用了 hexdigest() 方法生成可打印的摘要字符串。这个摘要字符串是由 digest() 方法生成的值的不同表现形式而已,这个值可能包括包括不可打印字符,包括 NUL。一些 web 服务(Google checkout, Amazon S3)使用了二进制摘要的 base64 版本而不是 hexdigest。

import base64
import hmac
import hashlibwith open('lorem.txt', 'rb') as f:body = f.read()hash = hmac.new(b'secret-shared-key-goes-here',body,hashlib.sha1,
)digest = hash.digest()
print(base64.encodestring(digest))

base64 编码的字符串以换行符结尾,当将字符串嵌入到 HTTP 头或者其他敏感的上下文中时,经常需要将这个换行符删除

b'olW2DoXHGJEKGU0aE9fOwSVE/o4=\n'

3.消息签名的应用

HMAC 算法应该用于任何公共网络服务,并且任何数据都应该存储在安全性很重要的地方。例如,当数据被通过管道或者 socket 发送的时候,数据应该被签名,然后在使用之前验签。此处给出的扩展示例位于文件 hmac_pickle.py。

第一步是创建一个函数计算一个字符串的摘要,以及一个简单的类,用于实例化并通过通信通道传递。

import hashlib
import hmac
import io
import pickle
import pprintdef make_digest(message):"Return a digest for the message."hash = hmac.new(b'secret-shared-key-goes-here',message,hashlib.sha1,)return hash.hexdigest().encode('utf-8')class SimpleObject:"""Demonstrate checking digests before unpickling."""def __init__(self, name):self.name = namedef __str__(self):return self.name

接下来,创建一个 BytesIO 缓冲池代表一个 socket 或者管道。例子中使用了一个原生的,但是很容易解析的,格式化的数据流。首先数据的摘要和长度被写入,后面紧跟了一个换行符。对象的序列化形式由 pickle 生成。真实的系统可能不希望依赖于长度值,因为如果摘要错误,则长度也是错误的。某些不太可能出现在实际数据中的终结符序列可能更加合适。

然后示例程序中往数据流中写入了两个对象。第一个是使用正确的摘要值写入的。

# 使用缓冲区模拟可写套接字或者管道
out_s = io.BytesIO()# 往流中写入一个有效的对象
#  digest\nlength\npickle
o = SimpleObject('digest matches')
pickled_data = pickle.dumps(o)
digest = make_digest(pickled_data)
header = b'%s %d\n' % (digest, len(pickled_data))
print('WRITING: {}'.format(header))
out_s.write(header)
out_s.write(pickled_data)

第二个写入流中的对象使用了一个无效的摘要值,摘要值是由其他一些数据生成的而不是序列化之后的值。

# 往流中写入一个无效的对象
o = SimpleObject('digest does not match')
pickled_data = pickle.dumps(o)
digest = make_digest(b'not the pickled data at all')
header = b'%s %d\n' % (digest, len(pickled_data))
print('\nWRITING: {}'.format(header))
out_s.write(header)
out_s.write(pickled_data)out_s.flush()

记住数据是在 BytesIO 缓冲池中的,它可以再次被读出。首先读取带有摘要和数据长度的行。然后使用长度值读取剩下的数据。pickle.load() 可以直接从流中读取数据,但是它假设一个可信任的数据流,而且这个数据还不足够可信能够反序列化它。从流中读取序列化值为字符串,而不实际反序列化更安全

# 使用 BytesIO 模拟可读的 socket 或者管道
in_s = io.BytesIO(out_s.getvalue())# 读取数据
while True:first_line = in_s.readline()if not first_line:breakincoming_digest, incoming_length = first_line.split(b' ')incoming_length = int(incoming_length.decode('utf-8'))print('\nREAD:', incoming_digest, incoming_length)

一旦序列化数据被读取到内存,摘要值可以被重新计算,并且使用 compare_digest() 同传递过来的数据比较。如果摘要匹配,证明它是安全的去信任数据并且反序列化它。

    incoming_pickled_data = in_s.read(incoming_length)actual_digest = make_digest(incoming_pickled_data)print('ACTUAL:', actual_digest)if hmac.compare_digest(actual_digest, incoming_digest):obj = pickle.loads(incoming_pickled_data)print('OK:', obj)else:print('WARNING: Data corruption')

输出表示第一个对象被验证通过,第二个被视为「损坏」

python3 hmac_pickle.pyWRITING: b'f49cd2bf7922911129e8df37f76f95485a0b52ca 69\n'WRITING: b'b01b209e28d7e053408ebe23b90fe5c33bc6a0ec 76\n'READ: b'f49cd2bf7922911129e8df37f76f95485a0b52ca' 69
ACTUAL: b'f49cd2bf7922911129e8df37f76f95485a0b52ca'
OK: digest matchesREAD: b'b01b209e28d7e053408ebe23b90fe5c33bc6a0ec' 76
ACTUAL: b'2ab061f9a9f749b8dd6f175bf57292e02e95c119'
WARNING: Data corruption

可以在定时攻击中使用简单的字符串或字节比较来比较两个摘要,以通过传递不同长度的摘要来暴露部分或全部秘密密钥。compare_digest() 实现了一个快速但是常量时间的比较函数去防止定时攻击。

相关文章:

hmac — 加密消息签名和验证

hmac — 加密消息签名和验证 1.概述 它的全称叫做Hash-based Message Authentication Code: 哈希消息认证码,从名字中就可以看出来这个hmac基于哈希函数的,并且还得提供一个秘钥key,它的作用就是用来保证消息的完整性,不可篡改。…...

AWS攻略——使用ACL限制访问

文章目录确定出口IP修改ACL修改主网络ACL修改入站规则修改子网ACL创建子网ACL新增入站规则新增出站规则关联子网假如我们希望限制只有公司内部的IP可以SSH登录到EC2,则可以考虑使用ACL来实现。 我们延续使用《AWS攻略——创建VPC》的案例,在它的基础上做…...

【已解决】关于 luckysheet 设置纯文本,解决日期格式回显错误的办法

目录 一、现象 二、分析 三、思考过程 五、解决 六、参考链接 一、现象 在excel里面输入内容,如 2023-2-17 12:00 保存后,传回后端的数据被转化成了 数值类型,这显然是一种困扰。 如图所示 二、分析 查阅了文档和一些博客发现 Lucky…...

Jackson

first you need to add dependence: gradle: implementation com.fasterxml.jackson.core:jackson-databind:2.13.1 implementation com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.1原生Jackson的使用示例: /*** 原生Jackson的使用示例*/ public class Jacks…...

字节软件测试岗:惨不忍睹的三面,幸好做足了准备,月薪19k,已拿offer

我今年25岁,专业是电子信息工程本科,19年年末的时候去面试,统一投了测试的岗位,软件硬件都有,那时候面试的两家公司都是做培训的,当初没啥钱,他们以面试为谎言再推荐去培训这点让我特别难受。后…...

vue使用axios发送post请求携带json body参数,后端使用@RequestBody进行接收

前言 最近在做自己项目中,做一个非常简单的新增用户场景,但是使用原生axios发送post请求的时候,还是踩了不少坑的。 唉,说多了都是泪,小小一个新增业务,在自己前后端一起开发的时候,硬是搞了好…...

【python百炼成魔】python之列表详解

文章目录一. 列表的概念1.1 列表是什么?1.2 为什么要使用列表?1.3 列表的定义二. 列表的增删改查操作2.1 列表的读取2.2 列表的切片2.3 列表的查询操作2.3.1 not in ,in 表达式2.3.2 列表元素遍历2.4 列表元素的增加操作2.4.1 append()的相关用法2.4.2 e…...

如何学习 Web3

在本文中,我将总结您可以采取的步骤来学习 Web3。从哪儿开始?当我们想要开始新事物时,我们需要一些指导,以免在一开始就卡住。但我们都是不同的,我们有不同的学习方式。这篇文章基于我学习 Web3 的非常个人的经验。路线…...

大数据框架之Hadoop:MapReduce(一)MapReduce概述

1.1MapReduce定义 MapReduce是一个分布式计算框架,用于编写批处理应用程序,是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一…...

一文搞定python语法进阶

前言前面我们已经学习了Python的基础语法,了解了Python的分支结构,也就是选择结构、循环结构以及函数这些具体的框架,还学习了列表、元组、字典、字符串这些Python中特有的数据结构,还用这些语法完成了一个简单的名片管理系统。下…...

2019蓝桥杯真题数列求值(填空题) C语言/C++

题目描述 本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。 给定数列 1,1,1,3,5,9,17,⋯,从第 4 项开始,每项都是前 3 项的和。 求第 20190324 项的最后 4 位数字。 运行限制 最大运行时间&#xff1a…...

spring中@Autowire和@Resource的区别在哪里?

介绍今天使用Idea写代码的时候,看到之前的项目中显示有warning的提示,去看了下,是如下代码?Autowire private JdbcTemplate jdbcTemplate;提示的警告信息Field injection is not recommended Inspection info: Spring Team recommends: &quo…...

算法训练营DAY54|583. 两个字符串的删除操作、72. 编辑距离

583. 两个字符串的删除操作 - 力扣(LeetCode)https://leetcode.cn/problems/delete-operation-for-two-strings/这道题也是对于编辑距离的铺垫题目,是可以操作两个字符串的删除,使得两个字符串的字符完全相同,这道题可…...

【Ctfshow_Web】信息收集和爆破

0x00 信息收集 web1 直接查看源码 web2 查看不了源码,抓包即可看到(JS拦截了F12) web3 抓包,发送repeater,在响应包中有Flag字段 web4 题目提示后台地址在robots,访问/robots.txt看到Disallow: /fl…...

基于机器学习的推荐算法研究与实现

摘要随着互联网的普及,人们可以通过搜索引擎、社交网络等方式获取大量的信息资源。但是,面对如此之多的信息,人们往往会感到迷失和困惑,无法快速准确地找到自己需要的信息。在这种情况下,推荐算法的出现为我们提供了一…...

(二十四)ATP应用测试平台——springboot集成fastdfs上传与下载功能

前言 本节内容我们主要介绍一下如何在springboot项目中集成fastdfs组件,实现文件的上传与下载。关于fastdfs服务中间键的安装过程,本节内容不做介绍。fastdfs是一个轻量级的分布式文件系统,也是我们文件存储中常常使用的组件之一&#xff0c…...

linux好用命令+vs快捷键

linux好用命令 功能指令跳转到vim界面的最后一行shift键g复制当前路径下所有文件和目录(加-r才行)到target目录cp -r * /home/target删除指定文件rm -rf test.txt文件重命名(-i交互式提示)mv -i file1 file2移动某个内容&#xf…...

Git 构建分布式版本控制系统

版本控制概念Gitlab部署1.版本控制概念 1.1分类 (一)1 本地版本控制系统(传统模式) (二)2 集中化的版本控制系统 CVS、Subversion(SVN) (三)3 分布式…...

Day891.一主多从的切换正确性 -MySQL实战

一主多从的切换正确性 Hi,我是阿昌,今天学习记录的是关于一主多从的切换正确性的内容。 在切换任务的时候,要先主动跳过这些错误,通过主动跳过一个事务或者直接设置跳过指定的错误,用GTID解决找同步位点的问题 大多…...

【论文笔记】图像修复Learning Joint Spatial-Temporal Transformations for Video Inpainting

论文地址:https://arxiv.org/abs/2007.10247 源码地址:GitHub - researchmm/STTN: [ECCV2020] STTN: Learning Joint Spatial-Temporal Transformations for Video Inpainting 一、项目介绍 当下SITA的方法大多采用注意模型,通过搜索参考帧…...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

【JavaEE】-- HTTP

1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...

条件运算符

C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...