zoukankan      html  css  js  c++  java
  • 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;
    }

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

  • 相关阅读:
    用wamp配置的环境,想用CMD连接mysql怎么连
    Mysql删除表
    MySQL创建表
    Leetcode 130. Surrounded Regions
    Leetcode 111. Minimum Depth of Binary Tree
    Leetcode 110. Balanced Binary Tree
    Leetcode 98. Validate Binary Search Tree
    Leetcode 99. Recover Binary Search Tree
    Leetcode 108. Convert Sorted Array to Binary Search Tree
    Leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal
  • 原文地址:https://www.cnblogs.com/WQLong/p/11282596.html
Copyright © 2011-2022 走看看