用vue和go实现登录加密
前端使用CryptoJS默认加密方法:
var pass = CryptoJS.AES.encrypt(formData.password, key.value).toString()
使用 CryptoJS.AES.encrypt() 时不指定加密模式和参数时,CryptoJS 默认会执行以下操作
var encrypted = CryptoJS.AES.encrypt("明文", "密钥", {format: CryptoJS.format.OpenSSL // 关键!默认使用 OpenSSL 兼容格式}
).toString()
默认生成的加密数据包含:
头部标识:Salted__(8字节)
随机盐值:(8字节)
实际加密数据:密文数据(长度根据明文变化)
封装解密函数,go语言环境当中自带以下依赖,可以直接使用
package handlersimport ("crypto/aes""crypto/cipher""crypto/md5""encoding/base64""errors"
)// AesDecryptCBCOpenSSL 解密经过CryptoJS(AES-CBC模式)加密的字符串
// 参数:
// - cipherText: Base64编码的加密字符串(包含OpenSSL格式的salt头)
// - key: 用户提供的原始密钥
// 返回值:
// - 解密后的原始字符串
// - 错误信息(解密失败时)
func AesDecryptCBCOpenSSL(cipherText, key string) (string, error) {// 步骤1:Base64解码cipherBytes, err := base64.StdEncoding.DecodeString(cipherText)if err != nil {return "", err}// 步骤2:验证OpenSSL头部格式(CryptoJS默认生成的格式)// 前8字节应为 "Salted__" 后跟8字节的随机盐值if len(cipherBytes) < 16 || string(cipherBytes[:8]) != "Salted__" {return "", errors.New("invalid OpenSSL salted encryption format")}// 步骤3:提取盐值(第9-16字节)salt := cipherBytes[8:16]// 步骤4:通过EVP KDF生成实际的加密密钥和IVkeyAndIV := evpKDF([]byte(key), salt, 32, 16) // 生成32字节密钥+16字节IV// 分割密钥和初始化向量keyBytes := keyAndIV[:32]ivBytes := keyAndIV[32:]// 步骤5:获取真正的加密数据(移除头部和盐值)data := cipherBytes[16:]// 步骤6:创建AES-CBC解密器block, err := aes.NewCipher(keyBytes)if err != nil {return "", err}// 步骤7:执行解密(会原地修改data的内容)mode := cipher.NewCBCDecrypter(block, ivBytes)mode.CryptBlocks(data, data)// 步骤8:移除PKCS#7填充data = pkcs7Unpad(data, block.BlockSize())return string(data), nil
}// evpKDF 实现OpenSSL的EVP_BytesToKey密钥派生函数
// 参数:
// - password: 用户提供的原始密钥
// - salt: 随机盐值
// - keyLen: 需要的密钥长度(单位字节)
// - ivLen: 需要的IV长度(单位字节)
// 返回值:
// - 派生后的密钥和IV的字节组合
func evpKDF(password, salt []byte, keyLen, ivLen int) []byte {digest := md5.New()var prev []bytevar result []byte// 循环直到生成足够的密钥材料for len(result) < keyLen+ivLen {digest.Reset()digest.Write(prev) // 写入前次结果digest.Write(password) // 写入密码digest.Write(salt) // 写入盐值prev = digest.Sum(nil) // 计算MD5值result = append(result, prev...) // 累积结果}// 返回组合后的密钥和IVreturn result[:keyLen+ivLen]
}// pkcs7Unpad 移除PKCS#7填充
// 参数:
// - data: 解密后的字节数组(含填充)
// - blockSize: 块大小(AES为16字节)
// 返回值:
// - 移除填充后的原始数据
func pkcs7Unpad(data []byte, blockSize int) []byte {if len(data) == 0 {return nil}// 获取最后一个字节的填充值padLen := int(data[len(data)-1])// 验证填充有效性if padLen > len(data) || padLen > blockSize {// 无效填充直接返回原数据(可能需要处理错误)return data}// 移除填充return data[:len(data)-padLen]
}
go语言实现加密和解密:
package mainimport ("crypto/aes""crypto/cipher""crypto/rand""encoding/hex""errors""fmt""io"
)// AES-GCM 加密
func AesEncryptGCM(plaintext []byte, key []byte) ([]byte, error) {block, err := aes.NewCipher(key)if err != nil {return nil, err}gcm, err := cipher.NewGCM(block)if err != nil {return nil, err}nonce := make([]byte, gcm.NonceSize())if _, err := io.ReadFull(rand.Reader, nonce); err != nil {return nil, err}return gcm.Seal(nonce, nonce, plaintext, nil), nil
}// AES-GCM 解密
func AesDecryptGCM(ciphertext []byte, key []byte) ([]byte, error) {block, err := aes.NewCipher(key)if err != nil {return nil, err}gcm, err := cipher.NewGCM(block)if err != nil {return nil, err}nonceSize := gcm.NonceSize()if len(ciphertext) < nonceSize {return nil, errors.New("invalid ciphertext")}nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]return gcm.Open(nil, nonce, ciphertext, nil)
}func main() {key := []byte("0123456789abcdef0123456789abcdef") // 32 字节 = AES-256plaintext := []byte("SensitiveData需要加密的内容")// 加密ciphertext, _ := AesEncryptGCM(plaintext, key)fmt.Printf("加密后的 HEX: %x\n", ciphertext)//如果需要把加密后的字符串保存到数据库当中需要转为Base64 编码encoded := base64.StdEncoding.EncodeToString(ciphertext)user.Password = encoded // 存储安全编码后的字符串// 解密decode, _ := base64.StdEncoding.DecodeString(user.Password)decrypted, _ := AesDecryptGCM(decode, key)fmt.Printf("解密结果: %s\n", decrypted)
}
相关文章:
用vue和go实现登录加密
前端使用CryptoJS默认加密方法: var pass CryptoJS.AES.encrypt(formData.password, key.value).toString()使用 CryptoJS.AES.encrypt() 时不指定加密模式和参数时,CryptoJS 默认会执行以下操作 var encrypted CryptoJS.AES.encrypt("明文&quo…...
政府数据开放试点企业如何抢占特许经营协议黄金席位
首席数据官高鹏律师团队 《中共中央办公厅 国务院办公厅关于 加快公共数据资源开发利用的意见》的落地,标志着数据从“封闭管理的行政资源”正式转变为“可流通的市场要素”。但机遇与风险从来是一枚硬币的两面——特许经营协议的黄金席位背后,隐藏着…...
CSS 锚点滑动效果的技术
CSS 锚点滑动效果的技术 引言 介绍锚点滑动效果的概念及其在网页设计中的重要性。简要说明 基本锚点链接 如何使用HTML中的<a>标签创建基本的锚点链接。示例代码: <a href"#section1">跳转到第一部分</a> <div id"section…...

mac-M系列芯片安装软件报错:***已损坏,无法打开。推出磁盘问题
因为你安装的软件在Intel 或arm芯片的mac上没有签名导致。 首先打开任何来源操作 在系统设置中配置,如下图: 2. 然后打开终端,输入: sudo spctl --master-disable然后输入电脑锁屏密码 打开了任何来源,还遇到已损坏…...

Echart地图数据源获取
DataV.GeoAtlas地理小工具系列 选择需要的区域地图,选中后输出即可: 地图钻取代码 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>map</title><style>html, body, #map{margin: 0;…...

GNSS数据自动化下载系统的设计与实现
摘要 本文详细介绍了三种不同设计的GNSS数据自动化下载系统,分别针对IGS观测数据、GRACE-FO Level-1B数据以及通过代理服务器获取数据的需求场景。系统采用Python实现,具备断点续传、完整性校验、异常处理和进度显示等核心功能。实验结果表明࿰…...
MySQL 中 JOIN 和子查询的区别与使用场景
目录 一、JOIN:表连接1.1 INNER JOIN:内连接1.2 LEFT JOIN:左连接1.3 RIGHT JOIN:右连接1.4 FULL JOIN:全连接二、子查询:嵌套查询2.1 WHERE 子句中的子查询2.2 FROM 子句中的子查询2.3 SELECT 子句中的子查询三、JOIN 和子查询的区别3.1 功能差异3.2 性能差异3.3 使用场…...
【深度学习-Day 12】从零认识神经网络:感知器原理、实现与局限性深度剖析
Langchain系列文章目录 01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...
谈谈未来iOS越狱或巨魔是否会消失
2024年10月的预测,先说结论: 巨魔iOS17.1消失概率为99%。 因为巨魔强依赖的漏洞就是一个签名漏洞,攻击面有限又经过2轮修复,第3次出现漏洞的概率极低。而越狱的话由于系统组件和服务较多,所以出现漏洞概率高攻击面多&…...

Unity3D仿星露谷物语开发43之农作物生长
1、目标 把防风草种子种在地里,并展示植物种子,防风草种子将随着时间变化而生长成植株。 2、创建Crop.cs脚本 在Assets -> Scripts下创建新的目录命名为Crop,在其下创建新的脚本命名为Crop.cs。 代码如下: using System.C…...

从0到1上手Kafka:开启分布式消息处理之旅
目录 一、Kafka 是什么 二、Kafka 的基础概念 2.1 核心术语解读 2.2 工作模式剖析 三、Kafka 的应用场景 四、Kafka 与其他消息队列的比较 五、Kafka 的安装与配置 5.1 环境准备 5.2 安装步骤 5.3 常见问题及解决 六、Kafka 的基本操作 6.1 命令行工具使用 6.1.1 …...
GTS-400 系列运动控制器板卡介绍(三十四)---运动程序多线程累加求和
运动控制器函数库的使用 运动控制器驱动程序、dll 文件、例程、Demo 等相关文件请通过固高科技官网下载,网 址为:www.googoltech.com.cn/pro_view-3.html 1 Windows 系统下动态链接库的使用 在 Windows 系统下使用运动控制器,首先要安装驱动程序。在安装前需要提前下载运动…...

Python爬虫如何应对网站的反爬加密策略?
在当今的互联网环境中,网络爬虫已经成为数据采集的重要工具之一。然而,随着网站安全意识的不断提高,反爬虫技术也越来越复杂,尤其是数据加密策略的广泛应用,给爬虫开发者带来了巨大的挑战。本文将详细介绍Python爬虫如…...

第一次经历项目上线
这几天没写csdn,因为忙着项目上线的问题,我这阶段改了非常多的前端bug哈哈哈哈,说几个比较好的bug思想! 这个页面算是我遇到的比较大的bug,因为我一开始的逻辑都写好了,询价就是在点击快递公司弹出弹框的时…...

Conda配置完全指南——Windows系统Anaconda/Miniconda的安装、配置、基础使用、清理缓存空间和Pycharm/VSCode配置指南
本文同步发布在个人博客: Conda配置完全指南Conda 是一个开源的跨平台包管理与环境管理工具,广泛应用于数据科学、机器学习及 Python 开发领域。它不仅能帮助用户快速安装、更新和卸载第三方库,还能创建相互隔离的虚拟环境,解决不…...

Quasar组件 Carousel走马灯
通过对比两个q-carousel组件来,了解该组件的属性 官方文档请参阅:Carousel 预览 源代码 <template><div class"q-pa-md"><div class"q-gutter-md"><q-carouselv-model"slide"transition-prev&quo…...
AI日报 - 2024年5月17日
🌟 今日概览 (60秒速览) ▎🤖 大模型前沿 | OpenAI推出自主编码代理Codex;Google DeepMind发布Gemini驱动的编码代理AlphaEvolve,能设计先进算法;Meta旗舰AI模型Llama 4 Behemoth发布推迟。 Codex能并行处理多任务&…...
R语言数据框(datafram)数据的构建及简单分析
代码完成的功能: 创建数据集(数据框), 写入到文件中, 显示数据, 分组计算平均年龄, 在Rstudio中,创建R markdown或R notebook文件运行。以下是添加了注释的完整R代码࿰…...

风控域——风控决策引擎系统设计
摘要 本文详细介绍了风控决策引擎系统的设计与应用。决策引擎系统是一种智能化工具,可自动化、数据驱动地辅助或替代人工决策,广泛应用于金融、医疗、营销、风控等领域。文章阐述了决策引擎的核心功能,包括自动化决策、动态规则管理、实时处…...

CAPL Class: TcpSocket (此类用于实现 TCP 网络通信 )
目录 Class: TcpSocketacceptopenclosebindconnectgetLastSocketErrorgetLastSocketErrorAsStringlistenreceivesendsetSocketOptionshutdown函数调用的基本流程服务器端的基本流程客户端的基本流程Class: TcpSocket学习笔记。来自CANoe帮助文档。 Class: TcpSocket accept /…...

数据分析 —— 数据预处理
一、什么是数据预处理 数据预处理(Data Preprocessing)是数据分析和机器学习中至关重要的步骤,旨在将原始数据转换为更高质量、更适合分析或建模的形式。由于真实世界的数据通常存在不完整、不一致、噪声或冗余等问题,预处理可以…...

软件架构风格系列(4):事件驱动架构
文章目录 前言一、从“用户下单”场景看懂事件驱动核心概念(一)什么是事件驱动架构?(二)核心优势:解耦与异步的双重魔法 二、架构设计图:三要素构建事件流转闭环三、Java实战:从简单…...
windows系统各版本下载
以下各版本Windows系统链接来自网友整理,请通过迅雷或者其他支持ED2K或BT的下载工具进行下载。 注:以下为原版系统,未激活、非破解版,仅供下载体验学习,请勿从事商业活动。 Windows 11 Windows 11 (consumer editions…...

arduino平台读取鼠标光电传感器
鼠标坏掉了,大抵是修不好了。(全剧终—) 但是爱动手的小明不会浪费这个鼠标,确认外观没有明显烧毁痕迹后,尝试从电路板上利用光电传感器进行位移的测量,光电传感器(型号:FCT3065&am…...

【Linux网络】网络层
网络层 在复杂的网络环境中确定一个合适的路径 IP 协议 IPV4 点分十进制[0,255].[0,255].[0,255].[0,255]IPV6 IP地址目标网格目标主机 基本概念 主机:配有IP地址,但是不进行路由控制的设备;路由器:即配有IP地址,又能进行路由控制;节点:主机和路由器的统称。 两个问题 路…...
力扣-98.验证二叉搜索树
题目描述 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下: 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 class Solutio…...
5.17本日总结
一、英语 复习list2list29 二、数学 学习14讲部分内容 三、408 学习计组1.2内容 四、总结 高数和计网明天结束当前章节,计网内容学完之后主要学习计组和操作系统 五、明日计划 英语:复习lsit3list28,完成07年第二篇阅读 数学&#…...

大模型学习:Deepseek+dify零成本部署本地运行实用教程(超级详细!建议收藏)
文章目录 大模型学习:Deepseekdify零成本部署本地运行实用教程(超级详细!建议收藏)一、Dify是什么二、Dify的安装部署1. 官网体验2. 本地部署2.1 linux环境下的Docker安装2.2 Windows环境下安装部署DockerDeskTop2.3启用虚拟机平台…...
VSCode launch.json 配置参数详解
使用 launch.json 配置调试环境时,会涉及到多个参数,用于定义调试器的行为和目标执行环境。以下是一些常用的配置参数: 1、"type" :指定调试器的类型,例如 "node" 表示 Node.js 调试器࿰…...
pytest多种断言类型封装为自动化断言规则库
以下是将多种断言类型封装为自动化断言规则库的完整实现方案,包含基础验证规则和扩展机制: import re import time from jsonschema import validate, ValidationError from typing import Dict, Any, Optional, Callableclass ResponseValidator:"""自动...