最近捣鼓了一下js RSA前端加解密。是通过用jsencrypt.min.js来实现的,这个js本身自带了RSA公钥加密和RSA私钥解密。对一些短字符串加解密足够。但如果加密的和解密的内容比较长的时候,就会有问题。所以要进行分段加解密,参考了网上的一些例子。多少有点问题。所以自己捣鼓了一下。直接看看代码吧
需要注意一个问题:如果与JAVA后台数据交互。某些中文字符可能因为编码原因会乱码,可以加密前先进行 encodeURIComponent(s)。然后解密后在decode回来,就完美了。
先看看添加的方法吧。后面给下载链接:
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.encryptLong=function (d){
var k = this.key;
var maxLength = (((k.n.bitLength() + 7) >> 3) - 11);
try {
var lt = "";
var ct = "";
if (d.length > maxLength) {
lt = d.match(/.{1,117}/g);
lt.forEach(function (entry) {
var t1 = k.encrypt(entry);
ct += t1;
});
return hex2b64(ct);
}
var t = k.encrypt(d);
var y = hex2b64(t);
return y;
} catch (ex) {
return false;
}
}
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.decryptLong(sss);
js下载链接:点击打开链接