JSEncrypt長文本分段加解密

需求出發點

在進行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庫的後面,使用方法就是將原先加解密調用的方法換爲此處的兩個方法即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章