前端公钥加解密长字符串
引用的js下载:
百度压缩版引用地址:
1 |
|
微软压缩版引用地址:
2 |
|
官网jquery压缩版引用地址:
3 |
|
1 |
|
JSEncrypt.js 扩展方法
方式1 base64加解密
//需要先引入 JSEncrypt.js 和 jquery.base64.min.js
//长字符串加密-脚本扩展
JSEncrypt.prototype.encryptLong = function (string) {
var k = this.getKey();
var strings = $.base64.encode(string);
var encrypArray = new Array();
try {
var ct = "";
if (strings.length > 245) {
for (var i = 0; i < strings.length; i = i + 245) {
var str;
if (strings.length >= (i + 245)) {
str = strings.substring(i, i + 245);
} else {
str = strings.substring(i);
}
var t1 = k.encrypt(str);
encrypArray.push(hex2b64(t1));
}
return encrypArray;
}
var t = k.encrypt(strings);
encrypArray.push(hex2b64(t));
return encrypArray;
} catch (ex) {
return false;
}
};
//长字符串解密-脚本扩展
JSEncrypt.prototype.decryptLong = function (encrypArray) {
var key = this.getKey();
try {
var t3 = "";
for(var j=0; j < encrypArray.length; j++){
var t4 = key.decrypt(b64tohex(encrypArray[j]));
t3 += t4;
}
var strings = String($.base64.decode(t3));
return t3;
} catch (ex) {
return false;
}
};
方式2 转二进制后加解密
// 分段加密长字符串
JSEncrypt.prototype.encryptLong = function (text:string) {
let ct = "";
// RSA每次加密117bytes,需要辅助方法判断字符串截取位置
// 1.获取字符串截取点
const bytes = new Array();
bytes.push(0);
let byteNo = 0;
const len = text.length;
let c;
let temp = 0;
for (let i = 0; i < len; i++) {
c = text.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 (let i = 0; i < bytes.length - 1; i++) {
let str;
if (i == 0) {
str = text.substring(0, bytes[i + 1] + 1);
} else {
str = text.substring(bytes[i] + 1, bytes[i + 1] + 1);
}
const t1 = this.encrypt(str);
ct += t1;
}
if (bytes[bytes.length - 1] != text.length - 1) {
const lastStr = text.substring(bytes[bytes.length - 1] + 1);
ct += this.encrypt(lastStr);
}
return (ct);
}
const t = this.encrypt(text);
return t;
};
JSEncrypt.prototype.decryptLong = function (text:string) {
const maxLength = ((this.n.bitLength() + 7) >> 3);
try {
if (text.length > maxLength) {
let ct = "";
const lt = text.match(/.{1,256}/g);
lt.forEach((entry) => {
const t1 = this.decrypt(entry);
ct += t1;
});
return ct;
}
const y = this.decrypt(text);
return y;
} catch (ex) {
return false;
}
};
调用范例
//入参 公钥、待加密数据文本
function getEncryptData(publicKey, data){
//RSA_ 密钥空不加密
if(!publicKey || publicKey.trim() == ''){
return data;
}
var public_key = publicKey.trim();
//RSA公钥加密
var jsEncrypt = new JSEncrypt();
jsEncrypt.setPublicKey(public_key);
//数据加密
var encrypt_data = encodeURIComponent(jsEncrypt.encryptLong(data));
console.log(encrypt_data);
return encrypt_data;
}
//入参 公钥、待解密数据文本
function getEncryptData(publicKey, data){
//RSA_ 密钥空不加密
if(!publicKey || publicKey.trim() == ''){
return data;
}
var public_key = publicKey.trim();
//RSA公钥加密
var jsEncrypt = new JSEncrypt();
jsEncrypt.setPublicKey(public_key);
//数据加密
var encrypt_data = encodeURIComponent(jsEncrypt.decryptLong(data));
console.log(encrypt_data);
return encrypt_data;
}
注:该方案长文本解密,中文直接加密会出现乱码。
解决方案:后台加密之前,先将字符串encodeURI 转义后再加密,前端解密后,再decodeURIComponent 转义,则可避免该问题