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(/[ \r\n]+$/, "")), 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;
}

 

在這里一次性補全了,當時找了好多地方才把引入的方法補全。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM