前端学习笔记 2020-04-20
说明:为防止私钥泄漏,由服务端生成两对密钥,分别是(前端公钥+私钥,后端公钥加私钥),采用加解密模式为:前端使用后台公钥加密,使用前端私钥解密;后端使用前端公钥加密,使用后端私钥解密。前后端统一使用公钥加密,私钥解密
一、现在vue项目中安装依赖包jsencrypt
npm install jsencrypt --save-dev
二、在项目中新建jsencryptKey.js,用来存放公共加解密方法
三、jsencryptKey.js内引入依赖jsencrypt.js
四、加解密方法
//加密 //str 未加密字符串 export function getEncryCode(str){ //实例化JSEncrypt let jse = new JSEncrypt(); //加密公钥(由服务端生成) let pubKey = `-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmBjTNoNbIjrZVoEt5OBNM6zZ/ yDZ7wgv53A6ekTuAsqfJ3jXmLC7PqqrJxgqqDf2l72CnRC8ZxIAkiUBmIK/FIDrl qCBPl1h0Ym8qPLmUuv5l3xmhlb6+a/v22444PW/U6Ur0l1BvbCorrsWV3leFFfLZ 5oT4mq9jXzkQLv8F6wIDAQAB -----END PUBLIC KEY-----` jse.setPublicKey(pubKey); let data = jse.encrypt(str.toString()); // 进行加密 return data; }
//解密 //params 待解密字符串 export function sendEncryCode(params){ //实例化JSEncrypt let jse = new JSEncrypt(); //使用前端私钥解密(私钥由服务端生成) let privKey = `-----BEGIN PRIVATE KEY----- MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKYGNM2g1siOtlWg S3k4E0zrNn/INnvCC/ncDp6RO4Cyp8neNeYsLs+qqsnGCqoN/aXvYKdELxnEgCSJ QGYgr8UgOuWoIE+XWHRibyo8uZS6/mXfGaGVvr5r+/bbjjg9b9TpSvSXUG9sKiuu xZXeV4UV8tnmhPiar2NfORAu/wXrAgMBAAECf0qUfyPgHJv7f+z3FPBfQExNXS4J wm/Vu4uCTw7sLs6hcr48E/pR3rVq9U2uqRu7LTZdUg3Rk1b/7pB7F3LJPCuX5n/t nqcEWfWoyAc6wnVLffxkvx7toD7nMl7+2/LsUgSiY/QFdG43dKs+5rXuEOOwcZV/ tLdivN9SEN44mEECQQDXls/rpMPYnd0IHHqh6YZEA3dH1CZAWeW/4XF/BINW/02m jtoNr+sTcZN9ekaLFTQnF/jJRi35dNwGhroG+k/hAkEAxST9oYDugGPTbu81JU1p nO8tLQPHvpVu3lGQEFahWZi6j70FlhNEhX74lDLrhvTOI4ohzHX28pU5TbQkiyl/ SwJBALxQseHmFGR80HurVLtlnrB+TozhlWAUpolLRbZrnMY7T/qzQWk/Rxm+1dR/ IGuQ4/NaDyjRMot6Nk9FE+3QbEECQQCXib+MDVdHSXSUqTro2YB9KTxIhcdcL/Fw 4rEiXfTYshV1t447tcPN+bOJ9zokGrj5iIxCZcrU3O+XUwlkDxnRAkArwYiJZFlS Lu9zj+e03+kGWu6c/x8RRoLqfZcWFffBZlkxOHa06aN6jYCdJtRON43JUbynMvDY l5glkcwnZlbi -----END PRIVATE KEY-----` jse.setPrivateKey(privKey); let data = jse.decrypt(params); //解密 return data; }
五、使用rsa加解密过程中会出现待加密和待解密字符串过长情况,需要用到分段加解密
需要进入依赖包中修改jsencrypt.js 文件中方法,具体方法如下:
//分段加密 JSEncrypt.prototype.encryptLong = function (string){ var k = this.getKey(); // var maxLength = (((k.n.bitLength() + 7) >> 3) - 11);//117 try { var lt = ""; var ct = ""; //RSA每次加密117bytes,需要辅助方法判断字符串截取位置 //1.获取字符串截取点 var bytes = new Array(); bytes.push(0); var byteNo = 0; var len, c; len = string.length; var temp = 0; for (var i = 0; i < len; i++) { c = string.charCodeAt(i); if (c >= 0x010000 && c <= 0x10FFFF) { byteNo += 4; } else if (c >= 0x000800 && c <= 0x00FFFF) { byteNo += 3; } else if (c >= 0x000080 && c <= 0x0007FF) { byteNo += 2; } else { byteNo += 1; } if ((byteNo % 117) >= 114 || (byteNo % 117) == 0) { if (byteNo - temp >= 114) { bytes.push(i); temp = byteNo; } } } //2.截取字符串并分段加密 if (bytes.length > 1) { for (var i = 0; i < bytes.length - 1; i++) { var str; if (i == 0) { str = string.substring(0, bytes[i + 1] + 1); } else { str = string.substring(bytes[i] + 1, bytes[i + 1] + 1); } var t1 = k.encrypt(str); ct += t1; }; if (bytes[bytes.length - 1] != string.length - 1) { var lastStr = string.substring(bytes[bytes.length - 1] + 1); ct += k.encrypt(lastStr); // debugger; } return hex2b64(ct); } var t = k.encrypt(string); var y = hex2b64(t); return y; } catch (ex) { return false; } }
//分段解密长字符串 JSEncrypt.prototype.decryptLong = function (text) { // Return the decrypted string. // console.log(this); var k = this.getKey(); var maxLength = ((k.n.bitLength() + 7) >> 3); try { var str = b64tohex(text); //var b=hex2Bytes(str); var inputLen = str.length; var ct = ""; if (inputLen > maxLength) { var lt = str.match(/.{1,256}/g); lt.forEach(function (entry) { var t1 = k.decrypt(entry); ct += t1; }); return ct; } var y = k.decrypt(b64tohex(string)); return y; } catch (ex) { return false; } };
如果使用分段加密,别忘记修改jsencryptKey.js中引用的加解密方法
六、在公共请求js中引入方法并调用
备注:使用rsa对大段接口参数进行加解密会大大降低接口请求及回调速度,不建议使用,推荐使用AES非对称加解密,稍后会整理发出来
background-color: blue;background-color: yellow;<input type="button" value="变蓝" @click="changeColorT