用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)
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/79724.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/79724.shtml
英文地址,請注明出處:http://en.pswp.cn/web/79724.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

React百日學習計劃——Deepseek版

階段一&#xff1a;基礎鞏固&#xff08;1-20天&#xff09; 目標&#xff1a;掌握HTML/CSS/JavaScript核心語法和開發環境搭建。 每日學習內容&#xff1a; HTML/CSS&#xff08;1-10天&#xff09; 標簽語義化、盒模型、Flex布局、Grid布局、響應式設計&#xff08;媒體查詢…

WPF中如何自定義控件

WPF自定義控件簡化版&#xff1a;賬戶菜單按鈕&#xff08;AccountButton&#xff09; 我們以**“賬戶菜單按鈕”為例&#xff0c;用更清晰的架構實現一個支持標題顯示、漸變背景、選中狀態高亮**的自定義控件。以下是分步拆解&#xff1a; 一、控件核心功能 我們要做一個類似…

Deepseek+Xmind:秒速生成思維導圖與流程圖

deepseekxmind&#xff0c;快速生成思維導圖和流程圖 文章目錄 思維導圖deepseek筆記本 txt文件xmind 流程圖deepseekdraw.io 思維導圖 deepseek 筆記本 txt文件 將deep seek的東西復制到文本文件中&#xff0c;然后將txt文件拓展名改成md xmind 新建思維導圖----左上角三…

基于javaweb的SpringBoot愛游旅行平臺設計和實現(源碼+文檔+部署講解)

技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、小程序、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;免費功能設計、開題報告、任務書、中期檢查PPT、系統功能實現、代碼編寫、論文編寫和輔導、論文…

服務器機架的功能和重要性

服務器已經成為各個行業必不可少的網絡設備&#xff0c;而服務器機架則是數據中心和IT基礎設施中不可或缺的重要組成部分&#xff0c;服務器機架能夠為服務器和其他網絡設備提供物理支撐&#xff0c;同時還可以提供設備維護和管理等多種功能&#xff0c;本文就來介紹一下服務器…

游戲引擎學習第277天:稀疏實體系統

回顧并為今天定下基調 上次我們結束的時候&#xff0c;基本上已經控制住了跳躍的部分&#xff0c;達到了我想要的效果&#xff0c;現在我們主要是在等待一些新的藝術資源。因此&#xff0c;等新藝術資源到位后&#xff0c;我們可能會重新處理跳躍的部分&#xff0c;因為現在的…

阿克曼-幻宇機器人系列教程1- 實現上位機與下位機交互的兩種方式

1. 電腦與機器人通過SSH命令連接 1.1 將機器人上電 目的&#xff1a;將機器人變成熱點 目標&#xff1a;將電腦連接機器人網絡 熱點名稱&#xff1a;Huanyu-111 密碼&#xff1a;12345678 1.2 完成電腦與機器人之間的連接 實現&#xff1a;在電腦終端中執行命令通過SSH登錄…

Rust 中的 Pin 和 Unpin:內存安全與異步編程的守護者

在 Rust 的世界里&#xff0c;Pin 和 Unpin 是兩個看似不起眼、實則至關重要的概念。它們在內存安全和異步編程中扮演著關鍵角色&#xff0c;是 Rust 開發者必須掌握的知識。今天&#xff0c;就讓我們深入探討這兩個概念&#xff0c;看看它們是如何在 Rust 的生態系統中發揮作用…

如何界定合法收集數據?

首席數據官高鵬律師團隊 在當今數字化時代&#xff0c;數據的價值日益凸顯&#xff0c;而合法收集數據成為了企業、機構以及各類組織必須嚴守的關鍵準則。作為律師&#xff0c;深入理解并準確界定合法收集數據的范疇&#xff0c;對于保障各方權益、維護法律秩序至關重要。 一…

自動駕駛的“眼睛”:用Python構建智能障礙物檢測系統

自動駕駛的“眼睛”:用Python構建智能障礙物檢測系統 在自動駕駛技術日益成熟的今天,障礙物檢測系統成了汽車智能化不可或缺的部分。無論是高速公路上的突發狀況,還是城市街道中的行人與車輛,準確識別障礙物并及時反應,是保證行車安全的關鍵。 那么,我們如何用Python構…

19.Excel數據透視表:第2部分數據透視計算

一 日期組合 不想看具體是哪一天的收入&#xff0c;想看每個月的收入是多少&#xff0c;要對日期進行組合。 光標選中日期字段下的數據&#xff0c; 右鍵。 補充&#xff1a;第2種方法。 補充&#xff1a;可以同時選擇多個。 下面這個是錯誤的。 源數據里面有不同的年份&#x…

Eclipse 插件開發 6 右鍵菜單

Eclipse 插件開發 6 右鍵菜單 1 plugin.xml2 SampleHandler.java3 Activator.java 1 plugin.xml <?xml version"1.0" encoding"UTF-8"?> <?eclipse version"3.4"?> <plugin><!-- 定義命令 --><extension point&…

用vite腳手架建立 前端工程

? 參考 開始 | Vite 官方中文文檔 腳本 chcp 65001 echo 建立vite工程 set PRO_NAMEmy-vue-app call npm create vitelatest %PRO_NAME% --template vue cd ./%PRO_NAME%set NOW_PATH%cd% echo now_path %NOW_PATH% echo 點擊回車啟動vite工程&#xff0c;請訪問ht…

ESP32C3連接wifi

文章目錄 &#x1f527; 一、ESP32-C3 連接 Wi-Fi 的基本原理&#xff08;STA 模式&#xff09;? 二、完整代碼 注釋講解&#xff08;適配 ESP32-C3&#xff09;&#x1f4cc; 三、幾個關鍵點解釋&#x1f51a; 四、小結 &#x1f527; 一、ESP32-C3 連接 Wi-Fi 的基本原理&a…

LangSmith 基本使用教程

LangSmith 是一個強大的工具&#xff0c;可以幫助開發者追蹤、監控和分析語言模型應用程序的性能。下面我將介紹兩種基本的追蹤方式&#xff1a;追蹤 OpenAI 調用和追蹤整個應用程序。 1. 追蹤 OpenAI 調用 (Trace OpenAI calls) 這種方法主要用于追蹤對 OpenAI API 的調用&a…

Python基礎學習-Day23

目錄 基礎概念轉換器&#xff08;transformer&#xff09;估計器&#xff08;estimator&#xff09;管道&#xff08;pipeline&#xff09; 實例pipeline 基礎概念 pipeline在機器學習領域可以翻譯為“管道”&#xff0c;也可以翻譯為“流水線”&#xff0c;是機器學習中一個重…

相對論速度疊加公式與雙曲正切

復習下相對論速度疊加公式吧&#xff0c;物理&#xff0c;是不是很多人都忘了呀。假設速度為 u , v u,v u,v&#xff0c;那么疊加后的速度 w w w為&#xff1a; w u v 1 u v / c 2 w\frac{uv}{1uv/c^2} w1uv/c2uv? ??這個公式告訴我們&#xff0c;在一個速度為2/3光速的…

【前綴和】和為 K 的子數組(medium)

【前綴和】和為 K 的子數組 題目描述算法原理和細節問題代碼 題目描述 和為 K 的子數組 給定一個整數數組和一個整數 k &#xff0c;請找到該數組中和為 k 的連續子數組的個數。 示例 1&#xff1a; 輸入:nums [1,1,1], k 2 輸出: 2 解釋: 此題 [1,1] 與 [1,1] 為兩種不同的…

在Ubuntu服務器上部署Label Studio

一、拉取鏡像 docker pull heartexlabs/label-studio:latest 二、啟動容器 &#xff08;回到用戶目錄&#xff0c;例&#xff1a;輸入pwd&#xff0c;顯示 /home/<user>&#xff09; docker run -d --name label-studio -it -p 8081:8080 -v $(pwd)/mydata:/label-st…

MySQL 從入門到精通(三):日志管理詳解 —— 從排錯到恢復的核心利器

在 MySQL 數據庫的日常運維中&#xff0c;日志是定位問題、優化性能、數據恢復的核心工具。無論是排查服務器啟動異常&#xff0c;還是分析慢查詢瓶頸&#xff0c;亦或是通過二進制日志恢復誤刪數據&#xff0c;日志都扮演著 “數據庫黑匣子” 的角色。本文將深入解析 MySQL 的…