【JWT】jwt实现HS、RS、ES、ED签名与验签

JWT 实现 HSRSESED 签名与验签

签名方式算法密钥类型签名要点验签要点
HSHMAC-SHA256对称密钥- 使用 crypto/hmac 和对称密钥生成 HMAC 签名
- 将 header.payload 作为数据输入
- 使用同一密钥重新计算 HMAC 签名
- 比较计算结果与接收到的签名是否一致
RSRSA-SHA256公钥 + 私钥- 使用 crypto/rsa 生成 RSA 签名
- 私钥签名,输入为 header.payload 的哈希值
- 使用 crypto/rsa 验证 RSA 签名
- 公钥解密签名后,验证是否与输入哈希值匹配
ESECDSA-P256公钥 + 私钥- 使用 crypto/ecdsa 生成 ECDSA 签名
- 签名结果为 (r, s),序列化并编码为 Base64URL
- 使用 crypto/ecdsa 验证签名
- 解析签名为 (r, s),验证其与 header.payload 的哈希匹配
EDEd25519公钥 + 私钥- 使用 crypto/ed25519 私钥直接签名完整的 header.payload 数据
- 签名结果无需额外哈希处理
- 使用 crypto/ed25519 公钥直接验证签名是否匹配完整数据

签名与验签实现重点

  • es算法签名和验签时算法位数必须相同:ES算法在验签时必须严格使用与签名时相同位数的算法进行验证,这一点与其他算法有所不同。(其他算法不必相同) 说明如下:

  • 加密在这里插入图片描述

  • 验签 在这里插入图片描述

  • Base64URL 编码:JWT 的 HeaderPayload 都需编码。

  • 数据输入:签名计算与验证的输入数据始终是 Base64URL(Header) + "." + Base64URL(Payload)

  • 密钥管理:对称密钥 (HS) 要妥善分发,公私钥对 (RS/ES/ED) 要安全存储。


go案例

hs.go

package jwteximport ("github.com/golang-jwt/jwt/v5""log"
)type HS struct {Key        stringSignMethod HSSignMethod
}type HSSignMethod stringconst (HS256 HSSignMethod = "HS256"HS384 HSSignMethod = "HS384"HS512 HSSignMethod = "HS512"
)// hs HMAC(Hash-based Message Authentication Code)用的hash-based
func (hs *HS) getSignMethod() *jwt.SigningMethodHMAC {// *jwt.SigningMethodHMAC 是 jwt.SigningMethod 接口的具体实现之一。通过返回具体的实现类型,// 可以确保你使用的是 HMAC 签名方法,而不是其他类型的签名方法(如 RSA 或 ECDSA)。switch hs.SignMethod {case HS256:return jwt.SigningMethodHS256case HS384:return jwt.SigningMethodHS384case HS512:return jwt.SigningMethodHS512default:return jwt.SigningMethodHS256}
}// Sign 签名
func (hs *HS) Sign(data jwt.Claims) (string, error) {token := jwt.NewWithClaims(hs.getSignMethod(), data)sign, err := token.SignedString([]byte(hs.Key))if err != nil {log.Println(err)return "", err}return sign, nil
}// Verify 验签,获取数据
func (hs *HS) Verify(sign string, data jwt.Claims) error {_, err := jwt.ParseWithClaims(sign, data, func(token *jwt.Token) (interface{}, error) {return []byte(hs.Key), nil})return err
}

rsa.go 私钥签名、公钥验证

package jwteximport ("github.com/golang-jwt/jwt/v5""log"
)type RS struct {SignMethod RSSignMethodPublicKey  stringPrivateKey string
}type RSSignMethod stringconst (RS256 RSSignMethod = "RS256"RS384 RSSignMethod = "RS384"RS512 RSSignMethod = "RS512"
)func (rs *RS) getSignMethod() *jwt.SigningMethodRSA {switch rs.SignMethod {case RS512:return jwt.SigningMethodRS512case RS384:return jwt.SigningMethodRS384case RS256:return jwt.SigningMethodRS256default:return jwt.SigningMethodRS256}
}// Sign 签名	私钥签名、公钥验证
func (rs *RS) Sign(data jwt.Claims) (string, error) {token := jwt.NewWithClaims(rs.getSignMethod(), data)pKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(rs.PrivateKey))sign, err := token.SignedString(pKey)if err != nil {log.Println(err)return "", err}return sign, nil
}// Verify 验签,获取数据
func (rs *RS) Verify(sign string, data jwt.Claims) error {_, err := jwt.ParseWithClaims(sign, data, func(token *jwt.Token) (interface{}, error) {return jwt.ParseRSAPublicKeyFromPEM([]byte(rs.PublicKey))})return err
}

es.go 私钥签名、公钥验证

package jwteximport ("github.com/golang-jwt/jwt/v5""log"
)type ES struct {SignMethod ESSignMethodPublicKey  stringPrivateKey string
}type ESSignMethod stringconst (ES256 ESSignMethod = "ES256"ES384 ESSignMethod = "ES384"ES512 ESSignMethod = "ES512"
)func (es *ES) getSignMethod() *jwt.SigningMethodECDSA {switch es.SignMethod {case ES512:return jwt.SigningMethodES512case ES384:return jwt.SigningMethodES384case ES256:return jwt.SigningMethodES256default:return jwt.SigningMethodES256}
}// Sign 签名	私钥签名、公钥验证
func (es *ES) Sign(data jwt.Claims) (string, error) {token := jwt.NewWithClaims(es.getSignMethod(), data)pKey, err := jwt.ParseECPrivateKeyFromPEM([]byte(es.PrivateKey))if err != nil {log.Println(err)return "", err}sign, err := token.SignedString(pKey)if err != nil {log.Println(err)return "", err}return sign, nil
}// Verify 验签,获取数据
func (es *ES) Verify(sign string, data jwt.Claims) error {_, err := jwt.ParseWithClaims(sign, data, func(token *jwt.Token) (interface{}, error) {return jwt.ParseECPublicKeyFromPEM([]byte(es.PublicKey))})return err
}

ed.go 私钥签名、公钥验证

package jwteximport ("github.com/golang-jwt/jwt/v5""log"
)type ED struct {PrivateKey stringPublicKey  string
}// Sign 签名
func (ed *ED) Sign(data jwt.Claims) (string, error) {token := jwt.NewWithClaims(jwt.SigningMethodEdDSA, data)pKey, err := jwt.ParseEdPrivateKeyFromPEM([]byte(ed.PrivateKey))if err != nil {log.Println(err)return "", err}sign, err := token.SignedString(pKey)if err != nil {log.Println(err)return "", err}return sign, err
}// Verify 验签,并获取数据
func (ed *ED) Verify(sign string, data jwt.Claims) error {_, err := jwt.ParseWithClaims(sign, data, func(token *jwt.Token) (interface{}, error) {return jwt.ParseEdPublicKeyFromPEM([]byte(ed.PublicKey))})return err
}

jwt.go

package jwteximport ("github.com/golang-jwt/jwt/v5"
)type Data struct {Name   stringAge    intGender intjwt.RegisteredClaims
}type Jwt interface {Sing(data jwt.Claims) (string, error)Verify(sign string, data jwt.Claims) error
}

https://github.com/0voice

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/66939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

地址栏信息location

获取信息 页面跳转 location.href当前地址栏信息 location.assign()设置跳转新的页面 location.replace() location.reload()刷新页面

程序员转型测试:解锁漏洞挖掘新旅程

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 程序…

StarRocks常用命令

目录 1、StarRocks 集群管理&配置命令 2、StarRocks 常用操作命令 3、StarRocks 数据导入和导出 1、StarRocks 集群管理&配置命令 查询 FE 节点信息 SHOW frontends; SHOW PROC /frontends; mysql -h192.168.1.250 -P9030 -uroot -p -e "SHOW PROC /dbs;"…

08-ArcGIS For JavaScript-通过Mesh绘制几何体(Cylinder,Circle,Box,Pyramid)

目录 概述代码实现1、Mesh.createBox2、createPyramid3、Mesh.createSphere4、Mesh.createCylinder 完整代码 概述 对于三维场景而言,二位的点、线、面,三维的圆、立方体、圆柱等都是比较常见的三维对象,在ArcGIS For JavaScript中我们知道点…

Linux中page、buffer_head、bio的关系

在Linux中,page、buffer_head、bio这三个概念紧密相关,共同构成了块设备I/O和内存管理的重要部分,它们的联系主要体现在以下方面: page与buffer_head 基于page构建:buffer_head通常是基于page来构建的,一…

直线拟合例子 ,岭回归拟合直线

目录 直线拟合,算出离群点 岭回归拟合直线: 直线拟合,算出离群点 import cv2 import numpy as np# 输入的点 points np.array([[51, 149],[122, 374],[225, 376],[340, 382],[463, 391],[535, 298],[596, 400],[689, 406],[821, 407] ], dtypenp.float32)# 使用…

SpringCloud两种注册中心

SpringCloud 基本概念 系统架构 我们之前做的所有的项目都属于单体架构,下面我们将要学习更适合大型项目的分布式架构 单体架构: 将业务的所有功能几种在一个项目中开发,打成一个包部署。 优点:架构简单、部署成本低 缺点&am…

SpringAI 搭建智能体(二):搭建客服系统智能体

在现代人工智能应用中,智能体(Agent) 是一个重要的概念,它的核心能力是自主性与灵活性。一个智能体不仅能够理解用户的需求,还能拆解任务、调用工具完成具体操作,并在复杂场景中高效运行。在本篇博客中&…

SVN客户端使用手册

目录 一、简介 二、SVN的安装与卸载 1. 安装(公司内部一般会提供安装包和汉化包,直接到公司内部网盘下载即可,如果找不到可以看下面的教程) 2. 查看SVN版本 ​编辑 3. SVN卸载 三、SVN的基本操作 1. 检出 2. 清除认证数据 3. 提交…

HTML 文本格式化详解

在网页开发中,文本内容的呈现方式直接影响用户的阅读体验。HTML 提供了多种文本格式化元素,可以帮助我们更好地控制文本的显示效果。本文将详细介绍 HTML 中的文本格式化元素及其使用方法,帮助你轻松实现网页文本的美化。 什么是 HTML 文本格…

衡量算法性能的量级标准:算法复杂度

今天开始数据结构的学习!作为一大重点,拿出态度很重要,想要真实掌握,博客笔记自然少不了!重点全部上色!避免疏忽 下面我们从0基础开始学习今天的第一节!不用担心看不懂,拒绝枯燥的理…

Spring Boot Starter介绍

前言 大概10来年以前,当时springboot刚刚出现并没有流行,当时的Java开发者们开发Web应用主要是使用spring整合springmvc或者struts、iBatis、hibernate等开发框架来进行开发。项目里一般有许多xml文件配置,其中配置了很多项目中需要用到的Be…

Java面试题2025-Spring

讲师:邓澎波 Spring面试专题 1.Spring应该很熟悉吧?来介绍下你的Spring的理解 1.1 Spring的发展历程 先介绍Spring是怎么来的,发展中有哪些核心的节点,当前的最新版本是什么等 通过上图可以比较清晰的看到Spring的各个时间版本对…

Linux 切换到 Root 用户的方式及差异详解

在 Linux 系统中,切换到 root 用户进行管理和操作是常见需求。不同的切换方法会影响环境变量、工作目录以及加载的配置文件。本文将介绍几种常用的切换方式及它们的特点。 切换到 Root 用户的主要方式 1. sudo su 这是通过 sudo 提权后调用 su 切换到 root 用户的…

虹科分享 | 汽车NVH小课堂之听音辨故障

随着车主开始关注汽车抖动异响问题,如何根据故障现象快速诊断异响来源,成了汽修人的必修课。 一个比较常用的方法就是靠“听”——“听音辨故障”。那今天,虹科Pico也整理了几个不同类型的异响声音,一起来听听看你能答对几个吧 汽…

浅谈Redis

2007 年,一位程序员和朋友一起创建了一个网站。为了解决这个网站的负载问题,他自己定制了一个数据库。于2009 年开发,称之为Redis。这位意大利程序员是萨尔瓦托勒桑菲利波(Salvatore Sanfilippo),他被称为Redis之父,更…

element tbas增加下拉框

使用Tabs 标签页的label插槽,嵌入Dropdown 下拉菜单,实现Tabs 标签页增加下拉切换功能 Tabs 标签页 tab-click"事件"(这个事件当中到拥有下拉框的tab里时,可以存一下Dropdown 第一个菜单的id,实现点击到拥有…

SQL-leetcode—1179. 重新格式化部门表

1179. 重新格式化部门表 表 Department: ---------------------- | Column Name | Type | ---------------------- | id | int | | revenue | int | | month | varchar | ---------------------- 在 SQL 中,(id, month) 是表的联合主键。 这个表格有关…

【Address Overfitting】解决过拟合的三种方法

目录 1. 收集更多数据实践方法:适用场景:优缺点: 2. 特征选择方法介绍:实践示例:适用场景:优缺点: 3. 正则化(Regularization)正则化类型:实践示例&#xff1…

面向通感一体化的非均匀感知信号设计

文章目录 1 非均匀信号设计的背景分析1.1 基于OFDM波形的感知信号1.2 非均匀信号设计的必要性和可行性1.2 非均匀信号设计的必要性和可行性 3 通感一体化系统中的非均匀信号设计方法3.1 非均匀信号的设计流程(1)均匀感知信号设计(2&#xff0…