2.4goweb加解密和jwt
MD5的基本实现
1. 标准库调用
Go语言通过crypto/md5包提供MD5算法的实现。核心步骤包括:
- 创建哈希对象:使用
md5.New()生成一个实现了hash.Hash接口的实例。 - 写入数据:通过
Write()方法或io.WriteString()将数据写入哈希对象。 - 生成哈希值:调用
Sum(nil)获取哈希结果,并通过encoding/hex包转换为十六进制字符串。
示例代码:
package mainimport ("crypto/md5""encoding/hex""fmt""io"
)func main() {h := md5.New()io.WriteString(h, "Hello, world!")hash := h.Sum(nil)fmt.Println(hex.EncodeToString(hash)) // 输出:6cd3556deb0da54bca060b4c39479839
}
此方法支持分块写入数据,适用于大文件处理
2. 简化方法
对于一次性计算,可直接使用md5.Sum()函数:
data := []byte("Hello, world!")
hash := md5.Sum(data)
fmt.Printf("%x\n", hash) // 输出:6cd3556deb0da54bca060b4c39479839
此方法直接返回固定长度的哈希数组(16字节),需手动转换为字符串
AES对称加解密
package mainimport ("bytes""crypto/aes""crypto/cipher""crypto/rand""encoding/base64""errors""fmt""io"
)func main() {// 示例密钥(AES-256需要32字节密钥)key := []byte("this-is-a-32-byte-key-1234567890")// 原始数据plaintext := []byte("今天是2025年4月12日,星期六,农历三月十五")fmt.Printf("原始数据: %s\n", plaintext)fmt.Printf("密钥: %s\n", key)// 加密ciphertext, err := AESEncrypt(key, plaintext)if err != nil {panic(err)}eb64 := base64.StdEncoding.EncodeToString(ciphertext)fmt.Printf("加密结果(Base64): %s\n", eb64)db64, _ := base64.StdEncoding.DecodeString(eb64)// 解密decrypted, err := AESDecrypt(key, db64)if err != nil {panic(err)}fmt.Printf("解密结果: %s\n", decrypted)
}// AESEncrypt 使用AES-256 CBC模式加密数据
func AESEncrypt(key, plaintext []byte) ([]byte, error) {block, err := aes.NewCipher(key)if err != nil {return nil, err}// PKCS7填充plaintext = PKCS7Pad(plaintext, aes.BlockSize)// 生成随机IVciphertext := make([]byte, aes.BlockSize+len(plaintext))iv := ciphertext[:aes.BlockSize]if _, err := io.ReadFull(rand.Reader, iv); err != nil {return nil, err}// 加密mode := cipher.NewCBCEncrypter(block, iv)mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)return ciphertext, nil
}// AESDecrypt 使用AES-256 CBC模式解密数据
func AESDecrypt(key, ciphertext []byte) ([]byte, error) {block, err := aes.NewCipher(key)if err != nil {return nil, err}if len(ciphertext) < aes.BlockSize {return nil, errors.New("ciphertext too short")}// 提取IViv := ciphertext[:aes.BlockSize]ciphertext = ciphertext[aes.BlockSize:]// 解密mode := cipher.NewCBCDecrypter(block, iv)mode.CryptBlocks(ciphertext, ciphertext)// 去除PKCS7填充return PKCS7Unpad(ciphertext)
}// PKCS7Pad 实现PKCS7填充
func PKCS7Pad(data []byte, blockSize int) []byte {padding := blockSize - len(data)%blockSizepadText := bytes.Repeat([]byte{byte(padding)}, padding)return append(data, padText...)
}// PKCS7Unpad 去除PKCS7填充
func PKCS7Unpad(data []byte) ([]byte, error) {length := len(data)if length == 0 {return nil, errors.New("empty data")}padding := int(data[length-1])if padding < 1 || padding > aes.BlockSize {return nil, errors.New("invalid padding")}if length < padding {return nil, errors.New("data shorter than padding")}// 检查填充是否有效for i := 0; i < padding; i++ {if data[length-padding+i] != byte(padding) {return nil, errors.New("invalid padding")}}return data[:length-padding], nil
}
关键点说明
- 密钥长度:
- AES-256需要32字节(256位)的密钥
- 示例中使用了简单的字符串密钥,实际应用中应从安全源获取密钥
- 初始化向量(IV):
- 每次加密都生成随机IV,确保相同明文加密结果不同
- IV不需要保密,但必须不可预测
- 填充方案:
- 实现了PKCS7填充,确保数据长度是块大小的倍数
- 解密后自动去除填充
- 安全注意事项:
- 使用
crypto/rand生成随机数 - 解密时严格验证填充有效性
- 实际应用中应考虑添加消息认证码(MAC)防止篡改
- 使用
Go语言JWT实现
JWT(JSON Web Token)是一种基于JSON的开放标准(RFC 7519),用于在网络应用间安全地传输信息。其核心是通过签名和声明机制实现无状态身份验证,广泛应用于分布式系统、微服务架构和跨域认证场景
JWT结构组成
Header:算法类型和token类型
{"alg": "HS256","typ": "JWT"
}
Payload(载荷)
- 作用:携带声明(Claims),包含用户身份信息或其他业务数据。
- 声明分类:
- Registered Claims(标准声明):如
iss(签发者)、exp(过期时间)、sub(主题) - Public Claims(自定义声明):需避免与标准声明冲突,如用户角色
role。 - Private Claims(私有声明):业务自定义字段,如用户ID
user_id。
- Registered Claims(标准声明):如
-
{"sub": "1234567890","name": "John Doe","iat": 1516239022,"exp": 1744876800 // 2025年4月12日0时的Unix时间戳 }Registered Claims 标准声明列表
声明名称 全称 类型 必填 描述 issIssuer String 否 签发者标识,表示生成JWT的实体(如认证服务器地址) subSubject String 否 主题标识,表示JWT的核心主体(如用户ID或唯一标识) audAudience String 否 接收方标识,指定JWT的预期接收者(如客户端应用ID) expExpiration Time Number 否 过期时间,Unix时间戳,表示JWT失效时间(必须大于 iat)nbfNot Before Number 否 生效时间,Unix时间戳,表示JWT在此时间前不可用 iatIssued At Number 否 签发时间,Unix时间戳,记录JWT生成时间 jtiJWT ID String 否 唯一标识符,用于防止重放攻击(建议全局唯一)
Signature:对前两部分的签名
- 作用:验证JWT的完整性和真实性,防止篡改。
- 生成方式:对
Header和Payload的Base64编码字符串拼接后,使用密钥和算法生成签名。
完整实现示例
安装依赖
go get github.com/golang-jwt/jwt/v5
代码实现
package main import ("fmt""time""github.com/golang-jwt/jwt/v5"
)// 自定义Claims结构体
type CustomClaims struct {UserID string `json:"user_id"`Username string `json:"username"`jwt.RegisteredClaims // 内置标准声明(exp, iat, nbf等)
} var secretKey = []byte("your-256-bit-secret-2025-04-12")func main() {// 生成Token tokenString, err := GenerateToken("u10001", "张三")if err != nil {panic(err)}fmt.Printf("生成的Token: %s\n", tokenString)// 验证Token claims, err := ParseToken(tokenString)if err != nil {panic(err)}fmt.Printf("解析结果: %+v\n", claims)
}// GenerateToken 生成JWT Token
func GenerateToken(userID, username string) (string, error) {expiration := time.Now().Add(24 * time.Hour)claims := CustomClaims{UserID: userID,Username: username,RegisteredClaims: jwt.RegisteredClaims{ExpiresAt: jwt.NewNumericDate(expiration),IssuedAt: jwt.NewNumericDate(time.Now()),},}token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)return token.SignedString(secretKey)
}// ParseToken 解析验证JWT Token
func ParseToken(tokenString string) (*CustomClaims, error) {token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])}return secretKey, nil })if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {return claims, nil }return nil, err
}
相关文章:
2.4goweb加解密和jwt
MD5的基本实现 1. 标准库调用 Go语言通过crypto/md5包提供MD5算法的实现。核心步骤包括: 创建哈希对象:使用md5.New()生成一个实现了hash.Hash接口的实例。写入数据:通过Write()方法或io.WriteString()将数据写入…...
深入解析多表联查(MySQL)
前言 在面试中以及实际开发中,多表联查是每个程序员必备技能,下文通过最简单的学生表和课程表的实例帮大家最快入门多表联查技能。 建立数据表 1. 学生表(students) 创建学生表 CREATE TABLE students (student_id INT AUTO_…...
宇视设备视频平台EasyCVR打造智慧酒店安防体系,筑牢安全防线
一、需求背景 酒店作为人员流动频繁的场所,对安全保障与隐私保护有着极高的要求。为切实维护酒店内部公共区域的安全秩序,24小时不间断视频监控成为必要举措。通常情况下,酒店需在本地部署视频监控系统以供查看,部分连锁酒店还希…...
C++ 编程指南36 - 使用Pimpl模式实现稳定的ABI接口
一:概述 C 的类布局(尤其是私有成员变量)直接影响它的 ABI(应用二进制接口)。如果你在类中添加或修改了私有成员,即使接口不变,编译器生成的二进制布局也会变,从而导致 ABI 不兼容。…...
Linux中的文件传输(附加详细实验案例)
一、实验环境的设置 ①该实验需要两台主机,虚拟机名称为 L2 和 L3 ,在终端分别更改主机名为 node1 和 node2,在实验过程能够更好分辨。 然后再重新打开终端,主机名便都更改了相应的名称。 ②用 ip a 的命令分别查看两个主机的 …...
基于 OpenHarmony 5.0 的星闪轻量型设备应用开发——Ch2 OpenHarmony LiteOS-M 内核应用开发
写在前面: 此篇是系列文章《基于 OpenHarmony5.0 的星闪轻量型设备应用开发》的第 2 章。本篇介绍了如何在 OpenHarmony 5.0 框架下,针对 WS63 进行 LiteOS-M 内核应用工程的开发。 为了方便读者学习,需要OpenHarmony 5.0 WS63 SDK 的小伙伴可…...
论文阅读:2024-arxiv How to Steer LLM Latents for Hallucination Detection?
总目录 大模型安全相关研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 How to Steer LLM Latents for Hallucination Detection? https://arxiv.org/pdf/2503.01917 https://www.doubao.com/chat/2818934852496130 其它资料: https://blog.csdn.net/we…...
Linux--线程概念与控制
目录 1. Linux线程概念 1-1 什么是线程 1-2 分⻚式存储管理 1-2-1 虚拟地址和⻚表的由来 1-2-2 物理内存管理 1-2-3 ⻚表 1-2-4 ⻚⽬录结构 1-2-5 两级⻚表的地址转换 1-2-6 缺⻚异常 1-3 线程的优点 1-4 线程的缺点 1-5 线程异常 1-6 线程⽤途 2. Linux进程VS线…...
Python | kelvin波的水平空间结构
写在前面 简单记录一下之前想画的一个图: 思路 整体比较简单,两个子图,本质上就是一个带有投影,一个不带投影,通常用在EOF的空间模态和时间序列的绘制中,可以看看之前的几个详细的画法。 Python | El Ni…...
【音视频】SDL播放PCM音频
相关API 打开音频设备 int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained); desired:期望的参数。obtained:实际音频设备的参数,一般情况下设置为NULL即可。 SDL_AudioSpec typedef struct SDL_AudioSpec { i…...
BERT - Bert模型框架复现
本节将实现一个基于Transformer架构的BERT模型。 1. MultiHeadAttention 类 这个类实现了多头自注意力机制(Multi-Head Self-Attention),是Transformer架构的核心部分。 在前几篇文章中均有讲解,直接上代码 class MultiHeadAtt…...
【LeetCode 热题100】二叉树遍历入门:从中序遍历到层序与右视图(力扣94 / 102/199)(Go语言版)
🌳 二叉树遍历入门:从中序遍历到层序与右视图 本文涵盖 LeetCode 上的三道基础但极具代表性的二叉树遍历题: 二叉树的中序遍历 二叉树的层序遍历 二叉树的右视图 通过这些题目,我们将从 DFS 到 BFS,深入理解如何处理…...
docker创建容器添加启动--restart选项
一、通过 Docker 命令直接修改已启动的容器(推荐-已验证) 操作步骤: 1.执行更新命令: docker update --restartalways <容器名或ID>此命令会将容器的重启策略调整为 always(无论容器以何种状态退出࿰…...
一文读懂WPF系列之常用控件以及样式
WPF控件 控件分类概览常用控件常用控件代码示例和效果 样式与模板应用样式定义方式行内样式页面/窗口级资源样式(Local Resource)应用程序全局资源独立资源字典(ResourceDictionary)控件模板(ControlTemplate&…...
嵌入式硬件篇---单片机周期
文章目录 前言 前言 在单片机中,时序控制是其执行指令和协调外设的核心基础。以下是单片机中常见的各种周期及其详细说明,以层次结构展开: 时钟周期(Clock Cycle) 定义: 时钟周期是单片机的最小时间单位&a…...
【双指针】专题:LeetCode 283题解——移动零
移动零 一、题目链接二、题目三、题目解析四、算法原理两个指针的作用以及三个区间总结 五、与快速排序的联系六、编写代码七、时间复杂度、空间复杂度 一、题目链接 移动零 二、题目 三、题目解析 “保持非零元素的相对顺序”,比如,示例1中非零元素1…...
2025蓝桥杯JavaB组
说明 博主自己水平有限,而且答案也不一定对,下面代码和思路仅作分享。我只把我考场上做了的写出来了,有什么问题欢迎评论区交流。 A:逃离高塔 思路: 由于有了去年的经验,所以一上来我就是找规律…...
SQL学习--基础语法学习
SQL和excle对比 学习目标 单表查询 项目背景 SQL 练习环境 SQL Online Compiler - Next gen SQL Editor 商品信息表:https://study-zhibo.oss-cn-shanghai.aliyuncs.com/test/%E5%95%86%E5%93%81%E4%BF%A1%E6%81%AF%E8%A1%A8.csv 订单明细表:https://…...
MATLAB2022b安装
1 从百度网盘下载MATLAB2022b,下载完成后解压到某个文件夹; 链接: MATLAB2022b 提取码: 6666 2 打开解压后的文件夹,进入setup文件夹,双击打开“setup.exe”文件; 3 在弹出窗口中选择“高级选项”-->“我有文件安…...
如何更改OCP与metadb集群的连接方式 —— OceanBase运维管理
背景 许多用户都会借助OCP平台来进行OceanBase集群的运维与监控,且因为考虑单节点的OCP部署,在遇故障时可能会短时间出现无法管控 OceanBase集群,多数用户倾向于采用多节点方式来部署OCP,即 OCP的 metadb集群也是三节点的集群部署…...
HTTP实现心跳模块
HTTP实现心跳模块 使用轻量级的cHTTP库cpp-httplib重现实现HTTP心跳模块 头文件HttplibHeartbeat.h #ifndef HTTPLIB_HEARTBEAT_H #define HTTPLIB_HEARTBEAT_H#include <string> #include <thread> #include <atomic> #include <chrono> #include …...
架构总览怎么写,才算工业级?
📈系统架构文档是整个项目最重要的起点,但很多人第一章就“写穿了”: 不是写得太细,就是没有重点。想要写出高质量、能协作、能传承的架构文档,这一篇会告诉你应该怎么做—— ✅ 架构总览的终极目标 明确边界、定义角色、画清数据流 别讲执行细节,别深入函数调用。 ✅ 架…...
Python10天突击--Day 3:函数式编程突破
以下是 Python 中实现方法耗时统计装饰器的完整方案,包含同步/异步支持、多级嵌套调用统计、可视化输出和性能分析等高级功能: 基础版:同步方法计时装饰器 import time from functools import wrapsdef timeit(func):"""基础…...
Datawhale 入驻 GitCode:以开源力量推动 AI 教育公平与创新
在 AI 技术深度重塑教育生态的今天,国内首个 AI 开源学习社区 —— Datawhale 正式加入 GitCode 开源平台!作为覆盖全球 3000 高校、培养超百万 AI 人才的创新社区,Datawhale 将通过开源协作模式,为人工智能教育公平注入新动能&a…...
ChatDBA:一个基于AI的智能数据库助手
今天给大家介绍一个基于 AI 大语言模型实现数据库故障诊断的智能助手:ChatDBA。 ChatDBA 是由上海爱可生信息技术股份有限公司开发,通过对话交互,提供数据库故障诊断、专业知识学习、SQL 生成和优化等功能,旨在提升 DBA 工作效率。…...
MacOS中的鼠标、触控板的设置研究
一、背景和写这篇文章的原因 想搞清楚和配置好鼠标,比如解决好为什么我的滚动那么难用?怎么设置滚轮的方向跟windows相同?调整双击速度,调整鼠标滚轮左右拨动的"冷却时间"。 二、各种设置之详细解释 1. MacOS设置 -&…...
asp.net core 项目发布到 IIS 服务器
目录 一、VS2022 发布 二、设置IIS服务 三、配置IIS管理器 (一)打开IIS管理器 (二)添加站台 (三)配置应用程式集区 四、安装ASP.NET Core Hosting Bundle 五、设定IIS的日志位置 六、测试 一、VS2…...
如何解决线程安全问题(不涉及分布式情况)
线程安全问题本质 当多个线程并发操作共享资源(变量/对象)时,可能因非原子性操作或内存可见性问题导致数据不一致。 解决方案一:synchronized 关键字 实现方式: 实例方法同步锁 在实现Runnable接口的自定义线…...
Spring Boot(二十二):RedisTemplate的List类型操作
RedisTemplate和StringRedisTemplate的系列文章详见: Spring Boot(十七):集成和使用Redis Spring Boot(十八):RedisTemplate和StringRedisTemplate Spring Boot(十九)…...
【Nodebb系列】Nodebb笔记写入方案
NodeBB写入方案 前言 最近在整理以前记录的碎片笔记,想把它们汇总到NodeBB中,方便管理和浏览。但是笔记内容有点多,并且用发帖的形式写到NodeBB中会丢失时间信息,因此整理了一套NodeBB写入方案,大致流程如下…...
