前端查詢條件加密傳輸方案(SM2加解密)

一、需求背景

控臺項目甲方進行安全測試,測試報告其中一條:敏感信息明文傳輸

1

敏感信息明文傳輸

中危

查詢接口傳輸手機號、銀行卡號等敏感信息時未加密/脫敏處理。

二、解決方案

討論出的方案是通過前端查詢條件加密,后端對加密的數據解密的方式,加解密使用SM2國密方案。具體方案:

1.每次登錄進控臺時生成SM2公私鑰對,其中私鑰放進登錄的session user信息中,公鑰返回給前端;

2.前端拿到公鑰放入cookie,前端查詢條件使用cookie SM2公鑰加密放入臨時字段,傳輸時將臨時字段數據賦值給需要加密的字段,將加密后的數據發送post;(如果是對整個查詢條件加密則更簡單);

原傳輸參數:&regCapital=112&acct=6222081202000000206

原傳輸參數:&regCapital=112&acct=564a761bc0d8c260d84abf25fa516eb09f04cb49bfb557943060c0879a4159736a70f4b2463fc65941bd1f29731f35570467e98ec916d091ad651de7afeb1ac8ff1ac05a9bc6df12bbd447fa1dec75a517c611a8557fe7a8e378055cff3f3d4f299b69e621ebd1260cfd331167d45f03

3.后端接收到加密后的數據,使用session中私鑰進行解密。

三、代碼實現

1.Sm2Utils.java文件,包含生成公私鑰對,后端對前端加密數據解密的方法。

package com.xxx.xxx.util;import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;/*** @ClassName Sm2Utils* @Description 生成SM2公私鑰對* @Author whb* @Date 2024/10/9 15:53* @Version 1.0**/
public class Sm2Utils {private static final X9ECParameters SM2_EC_PARAMS = GMNamedCurves.getByName("sm2p256v1");private static final ECDomainParameters DOMAIN_PARAMS = new ECDomainParameters(SM2_EC_PARAMS.getCurve(),SM2_EC_PARAMS.getG(),SM2_EC_PARAMS.getN(),SM2_EC_PARAMS.getH());/*** 生成SM2密鑰對* @return String[0]=公鑰(04開頭未壓縮格式), String[1]=私鑰(64字符16進制)*/public static String[] generateKeyPair() {try {// 1. 初始化密鑰生成器ECKeyPairGenerator generator = new ECKeyPairGenerator();ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters(DOMAIN_PARAMS, new SecureRandom());generator.init(keyGenParams);// 2. 生成密鑰對AsymmetricCipherKeyPair keyPair = generator.generateKeyPair();// 3. 獲取私鑰(去掉前面的00)ECPrivateKeyParameters privateKeyParams = (ECPrivateKeyParameters) keyPair.getPrivate();String privateKey = leftPad(privateKeyParams.getD().toString(16), 64, '0');// 4. 獲取公鑰(04開頭未壓縮格式)ECPublicKeyParameters publicKeyParams = (ECPublicKeyParameters) keyPair.getPublic();ECPoint publicKeyPoint = publicKeyParams.getQ();String publicKey = "04" +leftPad(publicKeyPoint.getAffineXCoord().toBigInteger().toString(16), 64, '0') +leftPad(publicKeyPoint.getAffineYCoord().toBigInteger().toString(16), 64, '0');return new String[]{publicKey, privateKey};} catch (Exception e) {throw new RuntimeException("生成SM2密鑰對失敗", e);}}private static String leftPad(String input, int size, char padChar) {if (input.length() >= size) {return input;}StringBuilder sb = new StringBuilder(size);for (int i = input.length(); i < size; i++) {sb.append(padChar);}sb.append(input);return sb.toString();}/*** SM2解密* @param privateKeyHex 16進制私鑰(64字符)* @param cipherDataHex 加密數據(16進制字符串)* @return 解密后的原文*/public static String decrypt(String privateKeyHex, String cipherDataHex) {try {// 1. 驗證私鑰格式if (privateKeyHex == null || privateKeyHex.length() != 64) {throw new IllegalArgumentException("私鑰必須是64字符的16進制字符串");}// 2. 驗證加密數據格式if (cipherDataHex == null || cipherDataHex.length() < 194) {throw new IllegalArgumentException("加密數據格式不正確,長度不足");}// 3. 準備私鑰參數BigInteger privateKeyD = new BigInteger(privateKeyHex, 16);ECPrivateKeyParameters privateKeyParams = new ECPrivateKeyParameters(privateKeyD, DOMAIN_PARAMS);// 4. 初始化SM2解密引擎(使用C1C3C2模式與前端一致)SM2Engine engine = new SM2Engine(SM2Engine.Mode.C1C3C2);engine.init(false, privateKeyParams);// 5. 解碼加密數據byte[] cipherData = Hex.decode(cipherDataHex);// 6. 驗證數據頭if (cipherData[0] != 0x04) {throw new IllegalArgumentException("加密數據必須以04開頭");}// 7. 解密數據byte[] decrypted = engine.processBlock(cipherData, 0, cipherData.length);return new String(decrypted, "UTF-8");} catch (Exception e) {throw new RuntimeException("SM2解密失敗: " + e.getMessage(), e);}}/*** 生成SM2密鑰對* @return 包含私鑰(64字符)和公鑰(130字符04開頭)的數組*/public static Map<String, String> genSm2KeyPair() {try {Map<String, String> keyMap = new HashMap<>(2);String[] keys =  generateKeyPair();keyMap.put("sm2PriKey", keys[1]);keyMap.put("sm2PubKey", keys[0]);return keyMap;} catch (Exception e) {throw new RuntimeException("生成SM2密鑰對失敗", e);}}/*** SM2解密* @param cipherDataHex 前端加密后的16進制字符串* @param privateKeyHex 16進制格式的私鑰(64字符)* @return 解密后的原始字符串*/public static String queryDataSm2Decrypt(String cipherDataHex, String privateKeyHex) {return decrypt(privateKeyHex, "04"+cipherDataHex);}
}

2.login.java執行公私鑰對

SessionUser suer = new SessionUser(userInfo, custInfo, roleIdArray, roleName, roleRank);Map<String, String> sm2KeyMaps = Sm2Utils.genSm2KeyPair();suer.setSm2PriKey(sm2KeyMaps.get("sm2PriKey"));
SessionUser.pushUser(suer, request);.........//頁面使用SM2公鑰加簽sm2PubKey
mav.addObject("sm2PubKey", sm2KeyMaps.get("sm2PubKey"));

3.前端頁面對數據加密

登錄后js對公鑰存放到cookie中

jQuery.cookie("login_sm2pubkey","${sm2PubKey}");

頁面使用,先引用sm2.js,下載sm-crypto/dist at master · JuneAndGreen/sm-crypto · GitHub

<script type="text/javascript" src="${rc.contextPath}/js/sm-crypto/sm2.js${refreshDate}"></script>......<td scope="row"><input name="certNo" class="form-control" style="height:30px;width:300px;"/></td><td style="display:none"><input name="certNoSm2" class="form-control"/></td>......
//先對數據加密
encryptData("userInfoQueryForm");
//post發送
post......function encryptWithSM2(param,sm2PubKey) {// 執行SM2加密const cipherMode = 1; // 1 - C1C3C2 模式const encryptData = sm2.doEncrypt(param, sm2PubKey, cipherMode);return encryptData;}function encryptData(formid) {var sm2PubKey = jQuery.cookie("login_sm2pubkey");var formData=document.getElementById(formid);if (!formData.certNo.value == "") {formData.certNoSm2.value = encryptWithSM2(formData.certNo.value,sm2PubKey)}}

4.后端解密

String sm2HexD = SessionUser.getUser(request).getSm2PriKey();String certNo = queryForm.getCertNo();if (com.changingpay.commons.util.StringUtils.isNotEmpty(sm2HexD)) {certNo = Sm2Utils.queryDataSm2Decrypt(queryForm.getCertNo(),sm2HexD);}

四、SM2解密坑

1.前端使用cipherMode = 1; // 1 - C1C3C2 模式,后端解密也需要用C1C3C2 模式,不然報錯

2.后端解密時,需要對前端加密的數據前面加04,不然解密報錯Invalid point encoding 0x-。。

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

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

相關文章

【Python】Flask網頁

Flask第三方庫安裝命令&#xff1a;pip install flask代碼&#xff1a;from flask import Flask app Flask(__name__)app.route("/") def hello():return "Hello world!"if __name__ "__main__":app.run()其中的"Hello world!"可以改…

數字資產革命中的信任之錨:RWA法律架構的隱形密碼

首席數據官高鵬團隊律師創作&#xff0c;AI輔助 在數字經濟的浪潮中&#xff0c;資產的邊界正在被重新定義。當一塊地產、一筆應收賬款、甚至一份碳配額被轉化為鏈上的數字代幣時&#xff0c;技術的光芒固然耀眼&#xff0c;但真正決定其生命力的&#xff0c;是背后隱匿的“信…

mobaxterm終端sqlplus亂碼問題解決

背景。使用mobaxterm終端連接linux。在查詢數據庫表注釋時發現**&#xff1f;**中文亂碼。影響對表的分析。完成以下三個編碼設置再打開sqlplus查詢含中文的數據就正常了 總結。需要查看sqlplus的編碼是什么 SELECT parameter, value FROM nls_database_parameters WHERE pa…

一個簡單的分布式追蹤系統

1. 準備工作 導入必要的庫 import contextvars import time from typing import Any, Optional, Dict, List, Union from dataclasses import dataclass, field2. 定義上下文變量 # 定義兩個上下文變量&#xff0c;存儲當前 Span 和 Trace _current_span: contextvars.Conte…

【Qt】事件處理、事件分發器、事件過濾器

事件處理 一. 事件事件處理鼠標事件處理按鍵事件處理定時器事件處理窗口事件處理 二. 事件分發器三. 事件過濾器 雖然 Qt 是跨平臺的 C 開發框架&#xff0c;Qt 的很多能力其實是操作系統提供的&#xff0c;只不過 Qt 封裝了系統 API&#xff0c;程序是運行在操作系統上的&…

廣東省省考備考(第三十八天7.4)——言語理解:邏輯填空(題目訓練)

錯題解析 本題可從第二空入手&#xff0c;橫線處搭配“理論”&#xff0c;且根據“使得”可知&#xff0c;橫線處與前文構成因果關系&#xff0c;即“遺傳學的空白和古生物證據的缺乏”導致他的理論在某些方面存在不足&#xff0c;A項“捉襟見肘”指拉一拉衣襟&#xff0c;就露…

5G網絡切片技術

5G中的網絡切片技術是一種通過虛擬化將單一物理網絡劃分為多個獨立、可定制的虛擬網絡的技術&#xff0c;旨在滿足不同應用場景對網絡性能、帶寬、時延等需求的差異化要求。以下從技術原理、核心價值、應用場景、實現方式及未來趨勢五個維度展開分析&#xff1a;一、技術原理&a…

算法學習筆記:7.Dijkstra 算法——從原理到實戰,涵蓋 LeetCode 與考研 408 例題

在計算機科學領域&#xff0c;圖論算法一直占據著重要地位&#xff0c;其中 Dijkstra 算法作為求解單源最短路徑問題的經典算法&#xff0c;被廣泛應用于路徑規劃、網絡路由等多個場景。無論是算法競賽、實際項目開發&#xff0c;還是計算機考研 408 的備考&#xff0c;Dijkstr…

匯編 函數調用棧

前言 網上很多對函數棧的解釋&#xff0c;說的不是很清楚感覺&#xff0c;尤其是對到底是誰的棧&#xff0c;以及指令的微小但是很致命的細節沒說&#xff0c;特寫本文&#xff0c;一是幫助自己記憶&#xff0c;二是為了幫助大家&#xff0c;如有疏忽錯誤請指正。 核心概念 首先…

基于Apache MINA SSHD配置及應用

Apache MINA SSHD 是一個基于 Java 的 SSH 服務器和客戶端實現&#xff0c;它是 Apache MINA 項目的一部分&#xff0c;提供了完整的 SSH 協議支持。 主要特性 SSH 協議支持&#xff1a; 支持 SSH2 協議 兼容大多數 SSH 客戶端 支持多種加密算法和密鑰交換方法 服務器功能…

Excel 如何讓數據自動按要求排序或篩選?

讓數據按要求排序和篩選是Excel數據處理的基礎核心功能&#xff0c;也是進行有效分析前必做的準備工作。下面我們分開講解這兩個功能。 一、排序 (Sort)&#xff1a;讓數據井井有條 排序的目的是重新排列數據行的順序&#xff0c;以便更好地觀察和比較。 1. 快速單列排序 (最…

Django 安裝使用教程

一、Django 簡介 Django 是一個高級 Python Web 框架&#xff0c;鼓勵快速開發和簡潔實用的設計。它內置 ORM、認證系統、后臺管理、表單處理、路由控制等功能&#xff0c;廣泛用于開發企業級網站、內容管理系統、電商平臺等。 二、環境準備 2.1 安裝 Python Django 基于 Py…

前沿交叉:Fluent與深度學習驅動的流體力學計算體系

基礎模塊 流體力學方程求解 1、不可壓縮N-S方程數值解法&#xff08;有限差分/有限元/偽譜法&#xff09; Fluent工業級應用&#xff1a;穩態/瞬態流、兩相流仿真&#xff08;圓柱繞流、入水問題&#xff09; Tecplot流場可視化與數據導出 2、CFD數據的AI預處理 基于P…

五、Flutter動畫

目錄1. Flutter 中動畫的基本概念是什么&#xff1f;2. 解釋 AnimationController 和 Tween 的作用3. 如何實現一個補間&#xff08;Tween&#xff09;動畫&#xff1f;4. 什么是隱式動畫&#xff1f;舉例說明5. 如何實現自定義復雜動畫&#xff1f;1. Flutter 中動畫的基本概念…

全網唯一/Qt結合ffmpeg實現手機端采集攝像頭推流到rtsp或rtmp/可切換前置后置攝像頭/指定分辨率幀率

一、前言說明 之前已經實現了Qt結合ffmpeg在安卓上運行&#xff0c;所有在win上的功能&#xff0c;在安卓上都已經實現&#xff0c;比如編碼保存到MP4文件&#xff0c;正常解碼音視頻文件播放等&#xff0c;唯獨還差一個功能&#xff0c;盡管用的不多&#xff0c;但是還是有一…

Install Ubuntu 24.04 System

1.制作安裝鏡像盤&#xff08;U盤&#xff09; 下載rufus制作工具(網址&#xff1a;https://www.xiaomoxz.com/nexus/bi1/rufus4.shtml?bd_vid8643969197265870719&#xff09; 2. 設置U盤啟動&#xff1a; F2進入BIOS 3. Install Ubuntu 24.04 Ubuntu下載地址&#xff1a;…

solidjs 處理復雜類型的響應式

solidjs 處理復雜類型的響應式 在 solidjs 里響應式一般直接用 createSignal 就可以&#xff0c;但 createSignal 一般用于基礎數據類型。 雖然復雜類型也是可以使用&#xff0c;但基于起細粒度響應性的特性。 一般復雜的數據使用 createSignal 就不是那么友好了。 所以 cre…

爬蟲技術-獲取瀏覽器身份認證信息(如 Cookie、Token、Session 等)

方法一&#xff1a;通過瀏覽器開發者工具查看和提取 Cookie / Token &#x1f4cc; 示例場景&#xff1a; 你在使用一個網站時已經登錄了&#xff0c;想看看這個網站是如何保存你的身份憑證的。 &#x1f527; 操作過程&#xff1a; 打開瀏覽器&#xff08;例如 Chrome&#xf…

[密碼學實戰]GMT 0136-2024《密碼應用HTTP接口規范》解析

[密碼學實戰]GM/T 0136-2024《密碼應用HTTP接口規范》解析國家密碼管理局于2025年7月1日正式實施GM/T 0136-2024標準&#xff0c;該規范首次統一了密碼服務的HTTP接口設計&#xff0c;為國產密碼技術的規模化應用鋪平道路。本文結合標準原文&#xff0c;深入剖析其技術細節并給…

Docker 國內鏡像列表(免費長期)

Docker 可用鏡像源列表&#xff08;7月1日更新-長期維護&#xff09;_dockerhub國內鏡像源列表-CSDN博客