需求出發點
在進行RSA加密中,由於RSA的特性,一個1024位的密鑰只能加密117位字節數據,當數據量超過117位字節的時候,程序就會拋出異常,下面就給出如何完成前端RSA分段解密和後端RSA分段解密。js加密庫使用的是比較成熟的JSEncrypted,地址是https://github.com/travist/jsencrypt/tree/master/bin 下載相應的js文件。
代碼開發
對於加密我的方法就是判斷字符的特性,然後進行分段處理,循環加密處理。每次加密117bytes,最後合爲一體。代碼及註釋如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
/** * 長文本加密 * @param {string} string 待加密長文本 * @returns {string} 加密後的base64編碼 * */ JSEncrypt.prototype.encryptLong = function (string) { var k = this.getKey(); try { 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 += t1; } ; if (bytes[bytes.length - 1] != string.length - 1) { var lastStr = string.substring(bytes[bytes.length - 1] + 1); ct += k.encrypt(lastStr); } return hex2b64(ct); } var t = k.encrypt(string); var y = hex2b64(t); return y; } catch (ex) { return false; } }; |
如果後臺是node,那可以使用下面相應的長文本解密方法。其他語言代碼邏輯相同。思路就是117bytes的加密,解密使用128bytes位,也就是每128bytes位解密一次,最後拼接在一起。代碼及註釋如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/** * 長文本解密 * @param {string} string 加密後的base64編碼 * @returns {string} 解密後的原文 * */ JSEncrypt.prototype.decryptLong = function (string) { var k = this.getKey(); var maxLength = 128; try { var string = b64tohex(string); var ct = ""; if (string.length > maxLength * 2) { var lt = string.match(/.{1,256}/g); //128位解密。取256位 lt.forEach(function (entry) { var t1 = k.decrypt(entry); ct += t1; }); return ct; } var y = k.decrypt(string); return y; } catch (ex) { return false; } }; |
使用方法
將上面的兩段代碼加載JSEncrypt庫的後面,使用方法就是將原先加解密調用的方法換爲此處的兩個方法即可。