• JS-RSA请求数据加密


      最近公司要对前端请求数据进行RSA加密,所以在网上找了一些博客,并下载了一些demo测试了下,但不太乐观。目前网上的绝大部分博客对超长字符串(117位以上)加密不太支持或者支持的不太好。即使是付费的。。。

      所以我在网上的demo基础上,请教了下算法同学,经过测试,发现转化位二进制后,若第一位为0则会出现位数不够,同时导致解密失败。所以在原来的基础上进行了改进。

    一、引入js文件(下载地址:这里

    js/jsencrypt.min.js

    二、生产公私钥

    这一步的话,可以直接在网上找在线生成。

    三、定义方法

    这里需要重新定义两个方法:超长加密(encryptLong2)、超长解密(decryptLong2

    let encrypt = new JSEncrypt();  //  声明变量
        let b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        let b64pad = "=";
    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 += addPreZero(t1,256);
    }
    ;
    if (bytes[bytes.length - 1] != string.length - 1) {
    var lastStr = string.substring(bytes[bytes.length - 1] + 1);
    let rsaStr = k.encrypt(lastStr)
    ct += addPreZero(rsaStr,256);
    }
    //console.log("加密完的数据:"+ct);
    return hex2b64(ct);
    }
    var t = k.encrypt(string);
    var y = hex2b64(t);
    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;

    //分段解密
    console.log(inputLen +"----"+offSet)
    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;
    }
    }
     

    四、加密

    // 配置公钥
    encrypt.setPublicKey('MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCSLZqlbJchBRpyoBe1pWuoxV3At36hG85G3LikI7fiMRynou9nYz4a4T6uCtJNecFGdMPWPKtZ29/amgeFcHw/5vVEHuo8/JLFDM7u4P+cwTtBMwtsQCgynejfB0aOEp4NYjZTMmaeyRWCo5HOQahuV9LORyH/dWdD948qFsIFcQIDAQAB'); // 这里是配置公钥

    // 声明超长字符串
    let str = '{"latitude":"30.685632","longitude":"104.074092","appKey":"123412341234","channelId":"12341234","custId":"LASDFASWERSDFASDFASD","telephone":"2341234211234","token":"68d6a4c21170469289c42386b519612c","name":"王十二"}'
    // 加密
    var encryptData = encrypt.encryptLong2(str)  //  encryptData 为加密后的数据

    五、解密

    // 配置私钥
    encrypt.setPrivateKey('MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJItmqVslyEFGnKgF7Wla6jFXcC3fqEbzkbcuKQjt+IxHKei72djPhrhPq4K0k15wUZ0w9Y8q1nb39qaB4VwfD/m9UQe6jz8ksUMzu7g/5zBO0EzC2xAKDKd6N8HRo4Sng1iNlMyZp7JFYKjkc5BqG5X0s5HIf91Z0P3jyoWwgVxAgMBAAECgYAxsLrvHNjK6rcw2+bzYoYUWvMhvb6X+aHHSOSjN1kc1OEOwz5qgLvt2z+5XghbOdZPowWnX/xHkYyo/M8tty0k8EIAYK+tp8yfTMGIXBnSFhswtB6VDo5TQHU8o1DoD6xIime7PNL8avcjwT0XSH4tGoqWb+N2HzMegoAV0GgdgQJBAMezPNwhOwssEHvb116T+VjWYccuBF/F2nVnFS8XA/RTw3oA9a8luoNIc0Mt+TuBvPg4LzqWuFfdm/cinw7Ob1kCQQC7Y5NC4GBt5KilQaHvp0CVrXELk8HFLiF5bA69Na7WX+O+Jc9z4DDZrJ+tmc/ED2qaSAjapo7EQpko0e/8mVvZAkA4oYqbvky5IVjXVwOfTYVDfSAjVNhmtHv8GSx3uyYi7nIbshP6BE/9FNmi7nGkP2lwVraF/eHvAOhO0CGdGEuZAkBv2vB8axMkhellO9g+Bcg3kGB6WKjB2teAc1AZAYJr1LFNP6Sltp1yUei+56FtlwY7MeSXH/T4kgh6pVZrod+BAkEAs7ZBRtpURnz2yEJGpiMyWJDwyWgkiWufG3ShGcTIHkj4MEO3KX9uaJKw4VqQFs32U4mbucRQv9yvukhgUE+Www=='); // 解密
    var str2 = encrypt.decryptLong2(encryptData); //strs 为解密后数据,看看是否一致

    注:在定义方法时,需引入以下方法

    function hex2b64(h) {
            var i;
            var c;
            var ret = "";
            for (i = 0; i + 3 <= h.length; i += 3) {
                c = parseInt(h.substring(i, i + 3), 16);
                ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
            }
            if (i + 1 == h.length) {
                c = parseInt(h.substring(i, i + 1), 16);
                ret += b64map.charAt(c << 2);
            }
            else if (i + 2 == h.length) {
                c = parseInt(h.substring(i, i + 2), 16);
                ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
            }
            while ((ret.length & 3) > 0) ret += b64pad;
            return ret;
        }
        function hexToBytes(hex) {
            for (var bytes = [], c = 0; c < hex.length; c += 2)
                bytes.push(parseInt(hex.substr(c, 2), 16));
            return bytes;
        }
        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("");
        }
        function b64tohex(str) {
            for (var i = 0, bin = atob(str.replace(/[ 
    ]+$/, "")), hex = []; i < bin.length; ++i) {
                var tmp = bin.charCodeAt(i).toString(16);
                if (tmp.length === 1) tmp = "0" + tmp;
                hex[hex.length] = tmp;
            }
            return hex.join("");
        }
        function addPreZero(num,length){
            var t = (num+'').length,
            s = '';
            for(var i=0; i<length-t; i++){
            s += '0';
        }
      
     return s+num;
    }

    在这里一次性补全了,当时找了好多地方才把引入的方法补全。。。

  • 相关阅读:
    AspNetPage分页的RecordCount赋值问题
    bundle实现Activity之间的数据传递
    Windows Communication Foundation入门(Part Two) (转)
    数据库绑定TreeView,使用递归
    利用Repeater控件显示主-从关系数据表 (转)
    将TreeView中导出为XML数据
    JS调用WebService 无刷新获得在线消息
    table中取得各个单元格中的数据 parentElement children
    Oracle PL/SQL语言入门
    JavaScript直接导出Excel,Word
  • 原文地址:https://www.cnblogs.com/WQLong/p/11282596.html
Copyright © 2020-2023  润新知