最近捣鼓了一下js RSA前端加解密。是通过用jsencrypt.min.js来实现的,这个js本身自带了RSA公钥加密和RSA私钥解密。对一些短字符串加解密足够。但如果加密的和解密的内容比较长的时候,就会有问题。所以要进行分段加解密,参考了网上的一些例子。多少有点问题。所以自己捣鼓了一下。直接看看代码吧
需要注意一个问题:如果与JAVA后台数据交互,加密内容又特别长,比如好几千上万个字符。某些中文字符可能因为编码原因会乱码(少数)。英文字符完美。一般不影响正常业务使用。
先看看添加的方法吧。后面给下载链接:
1、添加两个转换函数
// Convert a hex string to a byte array function hexToBytes(hex) { for (var bytes = [], c = 0; c < hex.length; c += 2) bytes.push(parseInt(hex.substr(c, 2), 16)); return bytes; } // Convert a byte array to a hex string 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(""); }
2、添加分段加解密函数(分段解密有两个方法,建议用第二个)
JSEncrypt.prototype.encryptLong2 = function (string) { var k = this.getKey(); 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); } return hex2b64(ct); } var t = k.encrypt(string); var y = hex2b64(t); return y; } catch (ex) { return false; } }; JSEncrypt.prototype.decryptLong = function (string) { var k = this.getKey(); var maxLength = ((k.n.bitLength() + 7) >> 3); //var maxLength = 128; try { var str = b64tohex(string); //var b=hex2Bytes(str); var inputLen = str.length; var ct = ""; if (str.length > 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; } }; JSEncrypt.prototype.decryptLong2 = function (string) { var k = this.getKey(); // var maxLength = ((k.n.bitLength()+7)>>3); var MAX_DECRYPT_BLOCK = 128; try { var ct = ""; var t1; var bufTmp; var hexTmp; var str = b64tohex(string); 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; } else { bufTmp = buf.slice(offSet, inputLen); hexTmp = bytesToHex(bufTmp); t1 = k.decrypt(hexTmp); ct += t1; } offSet += MAX_DECRYPT_BLOCK; endOffSet += MAX_DECRYPT_BLOCK; } return ct; } catch (ex) { return false; } };
3用法:
//实例化加密对象 var encrypt = new JSEncrypt(); //设置加密公钥 encrypt.setPublicKey("......"); //分段加密 var sss=encrypt.encryptLong("这几天心里颇不宁静。今晚在院子里坐着乘凉,忽然想起日日走过的荷塘,"); alert(sss); //密文 var ttt=".........................."; //设置解密私钥 encrypt.setPrivateKey(".......") //分段解密 var sss= encrypt.decryptLong2(sss);js下载链接: 点击打开链接