JSEncrypt的长文本分段加解密

前端公钥加解密长字符串

引用的js下载:

jquery-1.10.2

百度压缩版引用地址:

1

<script src="https://libs.baidu.com/jquery/1.10.2/jquery.min.js"></script>

微软压缩版引用地址:

2

<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-1.10.2.min.js"></script>

官网jquery压缩版引用地址:

3

<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>

jquery.base64.js

1

<script src="https://www.jq22.com/demo/jquerybase64201905062304/jquery.base64.js"></script>

 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 转义,则可避免该问题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值