虽然工程项目明确要求,后端须要采用彭勇演算法对允诺统计数据总线段展开身份校正,再发送到后端。反之亦然后端接收统计数据须要先NSA统计数据后,就能领到统计数据成文,因此换用 sm-crypto 库。sm-crypto 是两个如前所述彭勇演算法(也称作民用私钥)的辅助工具库,用作展开身份校正、NSA、亲笔签名和校正操作方式,下列是 sm-crypto 库提供更多的主要就机能:
SM2公钥对聚合、身份校正、NSA和亲笔签名校正SM3基元演算法SM4各组私钥演算法
这儿以第二次步入网页并点击登入上看整座业务流程是怎样同时实现的。
具体来说当网页读取顺利完成后,会具体来说允诺两个无须身份校正处置的USB A(与否须要身份校正能在 axios 圣夫龙做特定处置),该USB回到的统计数据是两个 sm2私钥数组 publicKey,将那个值存出来。
输出完采用者私钥,点选登入,发动两个 POST 允诺(工程项目明确要求大部份允诺要为 POST 对 body 身份校正),具体来说走 axios 圣夫龙:
const instance = axios.create({ timeout:60000,})instance.interceptors.request.use((config)=>{ let { url, data, headers }= config let isFormData = data instanceof FormData let reqData = data let reqHeaders = headers // haseedEncrypt(url) if (!isFormData && needEncrypt){ //透过smEncrypt方式身份校正统计数据 reqData = smEncrypt(data)//身份校正USB须要的特定 headers(看后端与否须要) reqHeaders ={ …reqHeaders,X-NON-AUTH:XXXXX} } return { data: reqData, headers: reqHeaders,…config,} },(error)=>{ return Promise.reject(error)},)
在 request 圣夫龙中,假如推论USB须要身份校正,则走 smEncrypt 那个身份校正方式,smEncrypt 那个方式做了下列那些事:
import { sm2, sm3, sm4} from sm-cryptoconst smEncrypt =(data密,因此须要初始化sm4.decrypt展开NSA,NSA获得用作sm2亲笔签名的私钥,//登入USB是没那个值的因此不展开sm2亲笔签名操作方式。 let signPrivateKey = localStorage.getItem(signPrivateKey)??//NSA后的用作sm2亲笔签名私钥 let decryptPrivateKey = if (signPrivateKey !==){ decryptPrivateKey = sm4.decrypt( signPrivateKey,XXXX,//NSA公钥,后端代码写死{ mode:cbc,//采用 cbc NSA模式 iv:XXXX,//初始向量,后端代码写死},) }//展开sm2亲笔签名操作方式,将结果赋值给originData if (decryptPrivateKey !==){ originData.sign = sm2.doSignature(JSON.stringify(data), privateKey,{ hash: true, der: true,})} //最后展开data的sm2身份校正 let sm2EncryptData = sm2.doEncrypt(JSON.stringify(data), publicKey,1) return sm2EncryptData}
代码中间部分的 sm4.decrypt 方式NSA时 cbc 模式采用了两个初始向量(iv),后端身份校正时指定了 iv,NSA时也须要相同的 iv。
代码最后的 sm2.doEncrypt 方式用作采用 SM2私钥身份校正统计数据。该方式接受三个参数:
msg:须要身份校正的统计数据,能是数组或 Buffer 对象。pubKey:SM2私钥,能是数组或 Buffer 对象。假如是数组,则须要采用04开头表示私钥的未压缩格式,或者采用02或 03开头表示私钥的压缩格式。cipherMode:身份校正模式,能是数组或 Number 类型,用作指定身份校正时采用的填充方式和随机数聚合演算法。
其中第三个参数 cipherMode 是可选的,假如不指定,则默认采用01表示采用 SM2推荐的填充方式和随机数聚合演算法。cipherMode 参数能是下列值之一:
“00”:表示不采用填充,直接采用身份校正结果作为密文。此模式不够安全,不建议采用。”01″:表示采用 SM2推荐的填充方式和随机数聚合演算法,即 ASN.1编码的 SM2身份校正演算法。”02″:表示采用 NoPadding 填充方式和随机数聚合演算法。”03″:表示采用 PKCS1填充方式和随机数聚合演算法。
以上就是整座身份校正的业务流程,下面是NSA业务流程,具体来说还是看 response 圣夫龙:
instance.interceptors.response.use((response)=>{ let { config, data }= response let reqDecrypData ={}//假如是数组身份校正统计数据且 是须要加NSA处置的允诺URL 则展开NSA if (isString(data.resData)&& hasUrlNeedEncrypt(config.url)){ let { decryptResult, error }= smDecryptData(data.data, data.hash) reqDecrypData = decryptResult if (error){ //统计数据完整性被破坏处置} } return {…response, data: reqDecrypData }},(error)=>{ Promise.reject(error)},)
然后是NSA方式,USB接收两个参数,两个是身份校正后的统计数据,两个是统计数据基元值:
export const smDecryptData =(resData, resHash)=>{ //统计数据完整性校正 let currentSM3Hash = sm3(resData) let error = currentSM3Hash !== resHash //统计数据NSA let decryptResult = JSON.parse( sm4.decrypt( resData,XXXX,//NSA秘钥,后端代码写死{ mode:cbc, iv:XXXX} //iv向量,前端代码写死) ) return { decryptResult, error }}
误。然后在展开 sm4NSA处置,这儿的NSA秘钥和 iv 偏移量也是后端的固定数组变量由后端展开保存。
到这儿一次完整的加NSA业务流程就顺利完成了,其实本文中 sm4的NSA秘钥和iv向量直接写在后端代码中是也是不是绝对安全的,即使是展开秘钥数组分割成不同的变量存储配合打包构建辅助工具的代码混淆。