使用AES-CBC + HMAC-SHA256實現前后端請求安全驗證

AES-CBC + HMAC-SHA256 加密驗證方案,下面是該方案二等 優點缺點 表格,適用于文檔、評審或技術選型說明。

? 優點表格:AES-CBC + HMAC-SHA256 加密驗證方案

類別優點說明
🔐 安全性使用 AES-CBC 對稱加密使用 AES-128-CBC 是可靠且廣泛接受的對稱加密方式。
隨機生成 IV每次加密生成新的 IV,有效防止密文重放與模式識別。
HMAC-SHA256 簽名增強完整性校驗,防止中間人篡改密文。
加密前先簽名驗證防止不合法密文觸發解密報錯或被利用。
💡 靈活性簽名算法可切換支持從 HMAC-SHA256 切換為其他如 SHA-512。
密鑰可由 token 派生動態生成密鑰,便于用戶級安全控制。
前端跨平臺適用適用于 Web、小程序、移動端等多平臺前端環境。
🔁 可部署性可嵌入代理層Nginx + Lua 可提前攔截無效請求,節省后端資源。
🧩 多語言兼容Node.js、Python、Lua 等實現簡單支持常見語言和平臺,易于團隊協作與系統整合。

? 缺點表格:AES-CBC + HMAC 簽名方案的局限

類別缺點說明
?? 實現復雜度實現邏輯較多需要額外編碼 IV 管理、HMAC 簽名、前后端一致性等細節。
🔁 重放防護默認無時間戳或 nonce重放攻擊不可防,需要自行引入 timestamp + nonce 參數。
🔑 密鑰依賴密鑰動態性帶來兼容問題一旦 token 失效或更換,舊數據將無法解密。
📦 數據隨機訪問不支持局部解密AES-CBC 是塊加密,不能隨機訪問或解密數據片段。
🕒 不適合長期緩存密文隨機性增加校驗復雜度每次加密結果不同,不適合用于長期靜態存儲的校驗場景。

🧭 補充建議(可選擴展)

增強點建議
防重放在簽名前加上時間戳 + nonce 字段,防止多次使用舊數據
加密模式升級可考慮遷移到 AES-GCM,天然支持認證(AEAD)
秘鑰管理密鑰建議動態派生(如基于用戶會話、JWT claims 等)

下面是該方案的實現詳細代碼:


? 前端 JavaScript:frontend.js

// === frontend.js ===
// 前端:使用 AES-CBC 加密 + HMAC-SHA256 簽名
import aesjs from 'aes-js';
import CryptoJS from 'crypto-js';function aaa(token) {return aesjs.utils.utf8.toBytes(token.padEnd(16, '0').slice(0, 16));
}function generateRandomIV() {let iv = new Uint8Array(16);window.crypto.getRandomValues(iv);return iv;
}function getHmacSHA256(keyBytes, messageHex) {const keyHex = CryptoJS.enc.Hex.parse(aesjs.utils.hex.fromBytes(keyBytes));const hmac = CryptoJS.HmacSHA256(messageHex, keyHex);return hmac.toString(CryptoJS.enc.Hex);
}function encryptWithMac(token, plaintext) {const key = aaa(token);const iv = generateRandomIV();const textBytes = aesjs.utils.utf8.toBytes(plaintext);const padded = aesjs.padding.pkcs7.pad(textBytes);const aesCbc = new aesjs.ModeOfOperation.cbc(key, iv);const encryptedBytes = aesCbc.encrypt(padded);const ivHex = aesjs.utils.hex.fromBytes(iv);const ciphertextHex = aesjs.utils.hex.fromBytes(encryptedBytes);const fullDataHex = ivHex + ciphertextHex;const mac = getHmacSHA256(key, fullDataHex);return {data: fullDataHex,mac: mac};
}const token = 'abc123';
const msg = 'hello world';
const result = encryptWithMac(token, msg);
console.log(JSON.stringify(result));

? Node.js 后端驗證:backend_node.js

// backend_node.js
const crypto = require('crypto');function deriveKey(token) {return Buffer.from(token.padEnd(16, '0').slice(0, 16));
}function verifyEncryptedData(token, dataHex, macHex) {const key = deriveKey(token);const iv = Buffer.from(dataHex.slice(0, 32), 'hex');const ciphertext = Buffer.from(dataHex.slice(32), 'hex');// 驗證 HMACconst hmac = crypto.createHmac('sha256', key);hmac.update(dataHex);const expectedMac = hmac.digest('hex');if (expectedMac !== macHex) {throw new Error('MAC 驗證失敗');}// 解密const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);decipher.setAutoPadding(true);let decrypted = decipher.update(ciphertext, null, 'utf8');decrypted += decipher.final('utf8');return decrypted;
}// 示例
const token = 'abc123';
const { data, mac } = JSON.parse(/* 前端結果 */ '{"data": "...", "mac": "..."}');try {const plaintext = verifyEncryptedData(token, data, mac);console.log('解密成功:', plaintext);
} catch (e) {console.error(e.message);
}

? Python 后端驗證:backend_python.py

# backend_python.py
from Crypto.Cipher import AES
from Crypto.Hash import HMAC, SHA256
from binascii import unhexlifydef derive_key(token: str) -> bytes:return token.ljust(16, '0')[:16].encode()def verify_encrypted_data(token, data_hex, mac_hex):key = derive_key(token)iv = unhexlify(data_hex[:32])ciphertext = unhexlify(data_hex[32:])# 驗證 HMACh = HMAC.new(key, digestmod=SHA256)h.update(data_hex.encode())try:h.hexverify(mac_hex)except ValueError:raise ValueError('MAC 驗證失敗')# 解密cipher = AES.new(key, AES.MODE_CBC, iv)padded = cipher.decrypt(ciphertext)pad_len = padded[-1]return padded[:-pad_len].decode()# 示例
token = 'abc123'
data = '...'  # 前端 data
mac = '...'   # 前端 mactry:print('解密成功:', verify_encrypted_data(token, data, mac))
except Exception as e:print('失敗:', e)

? Nginx + Lua (OpenResty):aes_verify.lua

-- aes_verify.lua
local aes = require "resty.aes"
local hmac = require "resty.hmac"
local str = require "resty.string"
local cjson = require "cjson"ngx.req.read_body()
local body = ngx.req.get_body_data()
local json = cjson.decode(body)
local data = json.data
local mac = json.mac
local token = ngx.var.http_authorization:sub(8)local key = token .. string.rep("0", 16 - #token)
key = key:sub(1, 16)local hmac_obj = hmac:new(key, hmac.ALGOS.SHA256)
hmac_obj:update(data)
local expected_mac = str.to_hex(hmac_obj:final())if expected_mac ~= mac thenngx.status = 401ngx.say("MAC 驗證失敗")return ngx.exit(401)
endlocal iv = str.to_hex(data:sub(1, 32))
local cipher = data:sub(33)
local aes_cbc = aes:new(key, nil, aes.cipher(128, "cbc"), { iv = iv })
local decrypted = aes_cbc:decrypt(str.from_hex(cipher))
local pad = string.byte(decrypted:sub(-1))
decrypted = decrypted:sub(1, -pad-1)ngx.say("驗證通過,原文: ", decrypted)

配置片段:

location /api/secure-data {content_by_lua_file /etc/nginx/lua/aes_verify.lua;proxy_pass http://backend_service;
}

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

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

相關文章

Veins同時打開SUMO和OMNeT++的GUI界面

進入 Veins 工程目錄(即包含 sumo-launchd.py 的目錄),打開終端設置 SUMO_HOME 環境變量(指向你安裝的 SUMO 路徑): export SUMO\_HOME/home/veins/src/sumo-1.11.0編譯 Veins 工程(包含 OMNeT…

suricata之日志截斷

一、背景 在suricata的調試過程中,使用SCLogXXX api進行信息的輸出,發現輸出的日志被截斷了,最開始以為是解析邏輯有問題,沒有解析完整,經過排查后,發現SCLogXXX api內部進行了長度限制,最長2K…

navicat 如何導出數據庫表 的這些信息 字段名 類型 描述

navicat 如何導出數據庫表 的這些信息 字段名 類型 描述 數據庫名字 springbootmt74k 表名字 address SELECT COLUMN_NAME AS 字段名,COLUMN_TYPE AS 類型,COLUMN_COMMENT AS 描述 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA springbootmt74k AND TABLE_NAME a…

LVGL圖像導入和解碼

LVGL版本:8.1 概述 在LVGL中,可以導入多種不同類型的圖像: 經轉換器生成的C語言數組,適用于頁面中不常改變的固定圖像。存儲系統中的外部圖像,比較靈活,可以通過插卡或從網絡中獲取,但需要配置…

【Web前端開發】HTML基礎

Web前端開發是用來直接給用戶呈現一個一個的網頁,主要包含實現用戶的結構(HTML)、樣式(CSS)、交互(JavaScript)。然而一個軟件通常是由后端和前端完成的。可以查閱文檔:HTML 教程 (w…

MySQL 8.0 單節點部署與一主兩從架構搭建實戰

前言:在數據驅動的時代,數據庫作為數據存儲與管理的核心組件,其架構的選擇與配置對系統的性能、可用性和擴展性至關重要。MySQL 作為一款廣泛應用的開源關系型數據庫,憑借其穩定的性能和豐富的功能,深受開發者和企業的…

數據庫故障排查全攻略:從實戰案例到體系化解決方案

一、引言:數據庫故障為何是技術人必須攻克的 "心腹大患" 在數字化時代,數據庫作為企業核心數據資產的載體,其穩定性直接決定業務連續性。據 Gartner 統計,企業每小時數據庫 downtime 平均損失高達 56 萬美元&#xff0…

牛客周賽round91

C 若序列為1 4 5 7 9 1 2 3,1 9一定大于1 1或1 4...所以只需要記錄當前數之前數字的最大值,然后遍歷取max即可,所以對于上面的序列有效的比較為1 9,2 9,3 9取max 代碼 //求大于當前數的最大值,然后…

【MCAL】TC397+EB-tresos之I2c配置實戰(同步、異步)

I2C總線是Philips公司在八十年代初推出的一種串行、半雙工的總線,主要用于近距離、低速的芯片之間的通信。本篇文章首先從理論講起,介紹了英飛凌TC3x系列芯片對應MCAL中對I2C驅動的定義與介紹,建議讀者在閱讀本篇文章之前對I2C有個簡單的認識…

深拷貝與淺拷貝:理解 Python 中的對象復制機制

深拷貝與淺拷貝:理解 Python 中的對象復制機制 在 Python 編程中,對象的復制是一個常見的操作。然而,很多初學者在處理對象復制時會遇到困惑,尤其是在涉及到復雜數據結構(如列表、字典、自定義對象等)時。…

BeanPostProcessor和AOP

BeanPostProcessor Spring中有一個接口Oredr的getOrder()方法,這個方法返回值是一個int類型,Spring容器會根據這個方法的返回值 對容器的多個Processor對象從小到大排序,創建Bean時候依次執行他們的方法,也就是說getOrder()方法的…

拒絕服務攻擊(DoS/DDoS/DRDoS)詳解:洪水猛獸的防御之道

在數字時代,服務的可用性是衡量一個在線系統成功與否的關鍵指標之一。然而,存在一類被稱為"拒絕服務攻擊" (Denial of Service, DoS) 的網絡攻擊,其主要目的就是通過各種手段耗盡目標服務器或網絡的資源,使其無法響應正…

小剛說C語言刷題—1078求恰好使s=1+1/2+1/3+…+1/n的值大于X時n的值

1.題目描述 求恰好使 s11/21/3?1/n 的值大于 X 時 n 的值。( 2≤x≤10 ) 輸入 輸入只有一行,包括 1個整數 X 。 輸出 輸出只有一行(這意味著末尾有一個回車符號),包括 1 個整數。 樣例 輸入 2 輸出 4 2.參考代碼(C語言…

深度學習中的目標檢測:從 PR 曲線到 AP

深度學習中的目標檢測:從 PR 曲線到 AP 在目標檢測任務中,評估模型的性能是非常重要的。通過使用不同的評估指標和標準,我們可以量化模型的準確性與效果。今天我們將重點討論 PR 曲線(Precision-Recall Curve)、平均精…

MySQL 1366 - Incorrect string value:錯誤

MySQL 1366 - Incorrect string value:錯誤 錯誤如何發生發生原因: 解決方法第一種嘗試第二種嘗試 錯誤 如何發生 在給MySQL添加數據的時候發生了下面的錯誤 insert into sys_dept values(100, 0, 0, 若依科技, 0, 若依, 15888888888, ryqq.com, 0,…

[ctfshow web入門] web70

信息收集 使用cinclude("php://filter/convert.base64-encode/resourceindex.php");讀取的index.php error_reporting和ini_set被禁用了,不必管他 error_reporting(0); ini_set(display_errors, 0); // 你們在炫技嗎? if(isset($_POST[c])){…

Linux在web下http加密和配置虛擬主機及動態頁面發布

web服務器的數據加密 1.簡介:由于http協議以明文方式發送,不提供任何方式的數據加密,也不適合傳輸一些重要的信息,如銀行卡號、密碼等,解決該缺陷設計了安全套接字層超文本傳輸協議https; 2.https的握手流…

uni-app,小程序中的addPhoneContact,保存聯系人到手機通訊錄

文章目錄 方法詳解簡介 基本語法參數說明基礎用法使用示例平臺差異說明注意事項最佳實踐 方法詳解 簡介 addPhoneContact是uni-app框架提供的一個實用API,用于向系統通訊錄添加聯系人信息。這個方法在需要將應用內的聯系人信息快速保存到用戶設備通訊錄的場景下非…

NHANES稀有指標推薦:HALP score

文章題目:Associations of HALP score with serum prostate-specific antigen and mortality in middle-aged and elderly individuals without prostate cancer DOI:10.3389/fonc.2024.1419310 中文標題:HALP 評分與無前列腺癌的中老年人血清…

【django.db.utils.OperationalError: unable to open database file】

解決platform.sh 環境下,無法打開數據庫問題 場景 在platform.sh 執行python manage.py createsuperuser是提示 django.db.utils.OperationalError: unable to open database file 錯誤 原因 由于settings.py文件中 本地數據庫配置在線上配置后,導致…