1. 程式人生 > 其它 >VUE使用 sm-crypto 加解密以及簽名驗籤遇到的坑 (後端java)

VUE使用 sm-crypto 加解密以及簽名驗籤遇到的坑 (後端java)

技術標籤:前端javaVUEvue國密sm-crypto加密簽名

1.首先 一步一步來 安裝國密

npminstall--savesm-crypto

2.具體方法都有NPM 上都有

國密即國家密碼局認定的國產密碼演算法。主要有SM1,SM2,SM3,SM4。金鑰長度和分組長度均為128位。
1:SM1 為對稱加密。其加密強度與AES相當。該演算法不公開,呼叫該演算法時,需要通過加密晶片的介面進行呼叫。
2:SM2為非對稱加密,基於ECC。該演算法已公開。由於該演算法基於ECC,故其簽名速度與祕鑰生成速度都快於RSA。ECC 256位(SM2採用的就是ECC 256位的一種)安全強度比RSA 2048位高,但運算速度快於RSA。

3:SM3 訊息摘要。可以用MD5作為對比理解。該演算法已公開。校驗結果為256位。
4:SM4 無線區域網標準的分組資料演算法。對稱加密,金鑰長度和分組長度均為128位。

以上闡述借鑑的他人的描述

一共有兩對金鑰:一對兒服務端的;一對兒前端的

//服務端-gm公鑰-用於加密和驗籤[服務端公鑰前端拿]

varpublicKeyServer='xxxxx';

///服務端-gm私鑰-用於解密和生成簽名[服務端私鑰自己拿]

varprivateKeyServer='xxxxx';

//前端-gm公鑰-用於加密和驗籤[前端公鑰後端拿]

varpublicKeyWeb='xxxxxxx';

//前端-gm私鑰-用於解密和生成簽名[前端私鑰自己拿]

varprivateKeyWeb='xxxxxxx';

所以 就是前端拿服務端的公鑰publicKeyServer 進行加密跟驗證簽名 ;留自己的私鑰 privateKeyWeb進行解密跟生成簽名;同理服務也是如此拿前端公鑰及留下自己的私鑰

我要說的是 我在加解密的時候constcipherMode=1//1-C1C3C2,0-C1C2C3,預設為1 這個東西啊 你一定得配合後端來 ,因為你不確定後端是用的什麼加密方式,還存在一個補位的問題

什麼意思呢?就是 在加密的串前加上04,後端才能解密成功,同樣後端加密後也會返回帶04的加密串給前端(因為後端也是直接用別人的工具類),前端加密遇到04 的加密串且cipherMode為1的話必須去掉04 才能解密成功

const sm2 = require('sm-crypto').sm2;
const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,預設為1

var publicKeyServer = 'xxxxxxxxxxx';
var privateKeyWeb  = 'xxxxxxxx';


//此處若把加密串a給服務端則加上 04+a
var a=sm2.doEncrypt('SM2加解密注意事項', publicKeyServer, 1)
 console.log("SM2加密內容:"+a);

//如果自己前端解密後端返回的帶有04開頭的字串則去掉04後解密

var b=sm2.doDecrypt(a,privateKeyWeb,1) // 解密結果
console.log("sm2解密內容:"+b);

3.簽名驗證問題

如果是正常安裝npminstall--savesm-crypto 的話你會發現 這裡面有很多種簽名的方式 如果你聯調都通了 那就不用看下面得了

這個庫的簽名有很多種方式:但都不適用我目前遇到的問題 就是無法驗證簽名 後端是java 用的依賴如下:

<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.65</version>
</dependency>

我們遇到的問題 就是這個所有的簽名方式都過了 但後端都無法驗證簽名 所以就又找唄~找到這個https://github.com/JuneAndGreen/sm-crypto/issues/20庫的GitHubissues 上 有人問出"SM2自己簽名驗籤應該沒啥問題,但是和別的語言是不通的"

其中有個人提出 在他自己的GitHub上有個測試例子和java+js 的例子

他的專案中有提到簽名的問題 然後按照他的方式解決了簽名驗籤的問題

不用 sm-crypto 裡的所有簽名方式 什麼der,hash,userid,都無可奈何

就用https://github.com/lpilp/forhuahua 他的專案中有提到簽名的問題 然後按照他的方式解決了簽名驗籤的問題

簽名 :sm2.doSignature(msg, privateKey, { hash:true, der:true }))

驗籤:sm2.doVerifySignature(msg,vSign,publicKey,{hash:true,der:true})

const msg = 'hello'

constpublicKey='04ec7e40b8dfa4b14383f703ec5403b71db0ab505b9fc41f0df45a9910a307dfbd5b3c5afdd4b90d79fa0ab70d53fd88422df77e09b254a53e72b4857f74ab1da4'//公鑰

constprivateKey='58967e2beb6fffd3c96545eebd3000b39c10087d48faa0d41f9c7bf3720e0ea4'//私鑰

const verifyData=sm2.doSignature(msg,privateKey,{hash:true,der:true});

console.log(verifyData)

//這裡的vsign是java生成的

constvSign='30450220149d990885febfe0c399ac4481842a4452fb1e6a19de477ee5e5b7faac75686d022100be707161f13aacf6f5fd3a224a96faeee2309439767d4d0878bffafc8d86c6f6'

constver2=sm2.doVerifySignature(msg,vSign,publicKey,{hash:true,der:true})

到這兒,也就結束了 ,如果後端也有問題 讓後端參考https://github.com/ZZMarquis/gmhelper 這個人封裝的國密方法