1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 关于VUE中RSA分段加解密的解决方案

关于VUE中RSA分段加解密的解决方案

时间:2022-11-25 10:39:45

相关推荐

关于VUE中RSA分段加解密的解决方案

首先我们npm install jsencrypt --save把依赖下载下来

上次写的修改源码实在是太鸡肋了,所以说又改了下

rsa加密有长度限制

rsa算法本身要求加密内容也就是明文长度m必须0<m<密钥长度n。如果小于这个长度就需要进行padding,因为如果没有padding,就无法确定解密后内容的真实长度,字符串之类的内容问题还不大,以0作为结束符,但对二进制数据就很难,因为不确定后面的0是内容还是内容结束符。而只要用到padding,那么就要占用实际的明文长度,于是实际明文长度需要减去padding字节长度。我们一般使用的padding标准有NoPPadding、OAEPPadding、PKCS1Padding等,其中PKCS#1建议的padding就占用了11个字节。

这样,对于1024长度的密钥。128字节(1024bits)-减去11字节正好是117字节,但对于RSA加密来讲,padding也是参与加密的,所以,依然按照1024bits去理解,但实际的明文只有117字节了。

所以如果要对任意长度的数据进行加密,就需要将数据分段后进行逐一加密,并将结果进行拼接。同样,解码也需要分段解码,并将结果进行拼接。

解决方案

我是在utils文件里创建的rsa_s.js文件来写加解密方法:

//首先引入这个方法import JSEncrypt from 'jsencrypt'// 公钥keyconst publicKey = `-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKX1Fs2JUD25zrAEwPnjnZC0azrl1XjGzGrJ64eb1lr9QVVOO2zGKZdqDLZD4Ut4Mp6GHMaqqFXKm+zN7IAXu+mqZbUrqUziHE5YGC02wObiZEzfa6V9a8ZvqpB+Z8KO+hAkkjzjMl+E+hDORpZmez3SMzetn7mcCeLw8/vmxz3QIDAQAB-----END PUBLIC KEY-----`;// 私钥keyconst privateKey = `-----BEGIN PUBLIC KEY-----MIICXgIBAAKBgQDKX1Fs2JUD25zrAEwPnjnZC0azrl1XjGzGrJ64eb1lr9QVVOO2zGKZdqDLZD4Ut4Mp6GHMaqqFXKm+zN7IAXu+mqZbUrqUziHE5YGC02wObiZEzfa6V9a8ZvqpB+Z8KO+hAkkjzjMl+E+hDORpZmez3SMzetn7mcCeLw8/vmxz3QIDAQABAoGBAJBr6b4V6nJwXdHPyngy4PGl/HTqcK60BkTamALqzmEtU9tNU5z2yz7dy+6awTsjo7Vao8CwNrUp5fHGXw65EEc1/3Iu2Fiix0XF7RP4NFSoxbBmzQW1nUK/5DFi4VR1uhEmdbgLwGabsdqzeUqhRKkRGAPVCotBjaDBOu0J3Mu5AkEA+SM7Ctu7evOvZwjWrp9a5MGxJ9yLLabbIuWL+420jr2G6ojaTZ2ROA2DWWQPx4JqWxDHttomrb38dk2emP2WAwJBAM/yU58YRQ+dTeuTzNYC1JdWcs35n9+hoVP7y+x29CmcqDTPp3nRBbbq88yMb2nZdlwthWi7BurNHsRJFqj0GJ8CQF5gJCuW1UxcJ2PGi1yW7R2e6fcJqoden8B2aDKgmXdBAGyz7s5cE/jB1bH1H60aECPzFVSFCwXh5FMEUEHwPfUCQQC7JqZ57lbhebrSRcA58GwzFFvY40wu8gIHWvwqgti2xsZgWW+qZCPXf9gSBWaUhmJPDa0fGAxesGN7VyhswNuTAkEAzCFNqL/zwHXcwh9YyHTdk/bRWIJq49jTA+vbgGv0szKIvGRKoRbub3NEUiI80TDsCAvbJ6R80J7RjnpmShOwcA==-----END PUBLIC KEY-----`;//这里为分段加解密 也就是encryptLong 和 decryptLong 方法///// 16进制转byte数组function hexToBytes(hex) {for (var bytes = [], c = 0; c < hex.length; c += 2)bytes.push(parseInt(hex.substr(c, 2), 16));return bytes;}// byte数组转16进制function bytesToHex(bytes) {for (var hex = [], i = 0; i < bytes.length; i++) {hex.push((bytes[i] >>> 4).toString(16));hex.push((bytes[i] & 0xF).toString(16));}return hex.join("");};/*** Returns the pem encoded representation of the public key* If the key doesn't exists a new key will be created* @returns {string} pem encoded representation of the public key WITHOUT header and footer* @public*/JSEncrypt.prototype.encryptLong = function (string) {var k = this.getKey();try {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);}return hexToBytes(ct);}var t = k.encrypt(string);var y = hexToBytes(t);return y;} catch (ex) {return false;}};// utf-8数组转字符串function utf8ByteToUnicodeStr(utf8Bytes) {var unicodeStr = "";for (var pos = 0; pos < utf8Bytes.length;) {var flag = utf8Bytes[pos];var unicode = 0;if ((flag >>> 7) === 0) {unicodeStr += String.fromCharCode(utf8Bytes[pos]);pos += 1;} else if ((flag & 0xFC) === 0xFC) {unicode = (utf8Bytes[pos] & 0x3) << 30;unicode |= (utf8Bytes[pos + 1] & 0x3F) << 24;unicode |= (utf8Bytes[pos + 2] & 0x3F) << 18;unicode |= (utf8Bytes[pos + 3] & 0x3F) << 12;unicode |= (utf8Bytes[pos + 4] & 0x3F) << 6;unicode |= (utf8Bytes[pos + 5] & 0x3F);unicodeStr += String.fromCharCode(unicode);pos += 6;} else if ((flag & 0xF8) === 0xF8) {unicode = (utf8Bytes[pos] & 0x7) << 24;unicode |= (utf8Bytes[pos + 1] & 0x3F) << 18;unicode |= (utf8Bytes[pos + 2] & 0x3F) << 12;unicode |= (utf8Bytes[pos + 3] & 0x3F) << 6;unicode |= (utf8Bytes[pos + 4] & 0x3F);unicodeStr += String.fromCharCode(unicode);pos += 5;} else if ((flag & 0xF0) === 0xF0) {unicode = (utf8Bytes[pos] & 0xF) << 18;unicode |= (utf8Bytes[pos + 1] & 0x3F) << 12;unicode |= (utf8Bytes[pos + 2] & 0x3F) << 6;unicode |= (utf8Bytes[pos + 3] & 0x3F);unicodeStr += String.fromCharCode(unicode);pos += 4;} else if ((flag & 0xE0) === 0xE0) {unicode = (utf8Bytes[pos] & 0x1F) << 12;;unicode |= (utf8Bytes[pos + 1] & 0x3F) << 6;unicode |= (utf8Bytes[pos + 2] & 0x3F);unicodeStr += String.fromCharCode(unicode);pos += 3;} else if ((flag & 0xC0) === 0xC0) {//110unicode = (utf8Bytes[pos] & 0x3F) << 6;unicode |= (utf8Bytes[pos + 1] & 0x3F);unicodeStr += String.fromCharCode(unicode);pos += 2;} else {unicodeStr += String.fromCharCode(utf8Bytes[pos]);pos += 1;}}return unicodeStr;}/*** Returns the pem encoded representation of the public key* If the key doesn't exists a new key will be created* @returns {string} pem encoded representation of the public key WITHOUT header and footer* @public*/JSEncrypt.prototype.decryptLong = function (string) {var k = this.getKey();var MAX_DECRYPT_BLOCK = 128; //分段解密最大长度限制为128字节try {var ct = "";var t1;var bufTmp;var hexTmp;var str = bytesToHex(string); //这块可能有些没有必要,因为sting参数已经及转为byte数组var buf = hexToBytes(str);var inputLen = buf.length;//开始长度var offSet = 0;//结束长度var endOffSet = MAX_DECRYPT_BLOCK;//分段解密while (inputLen - offSet > 0) {if (inputLen - offSet > MAX_DECRYPT_BLOCK) {bufTmp = buf.slice(offSet, endOffSet);hexTmp = bytesToHex(bufTmp);t1 = k.decrypt(hexTmp);ct += t1;console.log('分段' + offSet)console.log(hexTmp)console.log(t1)} else {bufTmp = buf.slice(offSet, inputLen);hexTmp = bytesToHex(bufTmp);t1 = k.decrypt(hexTmp);ct += t1;console.log('分段' + offSet)console.log(hexTmp)console.log(t1)}offSet += MAX_DECRYPT_BLOCK;endOffSet += MAX_DECRYPT_BLOCK;}return ct;} catch (ex) {return false;}};//export default {/* JSEncrypt加密 */encrypt(data) {var jsencrypt = new JSEncrypt()console.log(jsencrypt)jsencrypt.setPublicKey(publicKey)var result = jsencrypt.encryptLong(data)return result},/* JSEncrypt解密 */decrypt(data) {var jsencrypt = new JSEncrypt()jsencrypt.setPrivateKey(privateKey)var result = jsencrypt.decryptLong(data)return result},}

这里我是在main.js中做的全局引入

import Rsa from "@/utils/rsa_s.js"

在页面中我们这样来使用

export default {data() {return {tableData: [{date: "-05-02",name: "王小虎",address: "上海市普陀区金沙江路 1518 弄",},{date: "-05-04",name: "王小虎",address: "上海市普陀区金沙江路 1517 弄",},{date: "-05-01",name: "王小虎",address: "上海市普陀区金沙江路 1519 弄",},{date: "-05-03",name: "王小虎",address: "上海市普陀区金沙江路 1516 弄",},],};},mounted() {console.log(this.Rsa);let locks = this.Rsa.encrypt(JSON.stringify(this.tableData));let keys = JSON.parse(this.Rsa.decrypt(locks));console.log(keys);// api().then((res) => {// if(res.data.code === '00000000') {// this.tableData = res;// }// });},};

最后得出的结果

好啦,到这里就可以看出我们的方案是成功的。支持小编,点个关注!阿巴阿巴阿巴~~~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。