RSA前臺加密後臺解密的應用

寫在前面

項目安全測試須要將登陸功能修改, AES加密不符合要求, 現改成RSA非對稱加密.(將登陸密碼加密後傳給後臺, 後臺解密後再進行一系列的校驗) .期間遇到了前臺js加密可是後臺解密失敗的問題http://www.javashuo.com/article/p-vszplbci-hc.html, 下面是看了另外一篇博客後正常加解密的步驟及關鍵代碼.html

步驟及關鍵代碼

0.pom.xml

<!--RSA-->
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.63</version>
</dependency>

<!--lang3-->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.9</version>
</dependency>

1.rsasecurity.js

 1 (function ($w) {  2 
 3     if (typeof $w.RSAUtils === 'undefined')  4         var RSAUtils = $w.RSAUtils = {};  5 
 6     var biRadixBase = 2;  7     var biRadixBits = 16;  8     var bitsPerDigit = biRadixBits;  9     var biRadix = 1 << 16;  10     var biHalfRadix = biRadix >>> 1;  11     var biRadixSquared = biRadix * biRadix;  12     var maxDigitVal = biRadix - 1;  13     var maxInteger = 9999999999999998;  14 
 15 
 16     var maxDigits;  17     var ZERO_ARRAY;  18     var bigZero, bigOne;  19 
 20     var BigInt = $w.BigInt = function (flag) {  21         if (typeof flag == "boolean" && flag == true) {  22             this.digits = null;  23         } else {  24             this.digits = ZERO_ARRAY.slice(0);  25  }  26         this.isNeg = false;  27  };  28 
 29     RSAUtils.setMaxDigits = function (value) {  30         maxDigits = value;  31         ZERO_ARRAY = new Array(maxDigits);  32         for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0;  33         bigZero = new BigInt();  34         bigOne = new BigInt();  35         bigOne.digits[0] = 1;  36  };  37     RSAUtils.setMaxDigits(20);  38 
 39 
 40     var dpl10 = 15;  41 
 42     RSAUtils.biFromNumber = function (i) {  43         var result = new BigInt();  44         result.isNeg = i < 0;  45         i = Math.abs(i);  46         var j = 0;  47         while (i > 0) {  48             result.digits[j++] = i & maxDigitVal;  49             i = Math.floor(i / biRadix);  50  }  51         return result;  52  };  53 
 54 
 55     var lr10 = RSAUtils.biFromNumber(1000000000000000);  56 
 57     RSAUtils.biFromDecimal = function (s) {  58         var isNeg = s.charAt(0) == '-';  59         var i = isNeg ? 1 : 0;  60         var result;  61 
 62         while (i < s.length && s.charAt(i) == '0') ++i;  63         if (i == s.length) {  64             result = new BigInt();  65         } else {  66             var digitCount = s.length - i;  67             var fgl = digitCount % dpl10;  68             if (fgl == 0) fgl = dpl10;  69             result = RSAUtils.biFromNumber(Number(s.substr(i, fgl)));  70             i += fgl;  71             while (i < s.length) {  72                 result = RSAUtils.biAdd(RSAUtils.biMultiply(result, lr10),  73  RSAUtils.biFromNumber(Number(s.substr(i, dpl10))));  74                 i += dpl10;  75  }  76             result.isNeg = isNeg;  77  }  78         return result;  79  };  80 
 81     RSAUtils.biCopy = function (bi) {  82         var result = new BigInt(true);  83         result.digits = bi.digits.slice(0);  84         result.isNeg = bi.isNeg;  85         return result;  86  };  87 
 88     RSAUtils.reverseStr = function (s) {  89         var result = "";  90         for (var i = s.length - 1; i > -1; --i) {  91             result += s.charAt(i);  92  }  93         return result;  94  };  95 
 96     var hexatrigesimalToChar = [  97         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',  98         'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',  99         'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 100         'u', 'v', 'w', 'x', 'y', 'z'
101  ]; 102 
103     RSAUtils.biToString = function (x, radix) { 104         var b = new BigInt(); 105         b.digits[0] = radix; 106         var qr = RSAUtils.biDivideModulo(x, b); 107         var result = hexatrigesimalToChar[qr[1].digits[0]]; 108         while (RSAUtils.biCompare(qr[0], bigZero) == 1) { 109             qr = RSAUtils.biDivideModulo(qr[0], b); 110             digit = qr[1].digits[0]; 111             result += hexatrigesimalToChar[qr[1].digits[0]]; 112  } 113         return (x.isNeg ? "-" : "") + RSAUtils.reverseStr(result); 114  }; 115 
116     RSAUtils.biToDecimal = function (x) { 117         var b = new BigInt(); 118         b.digits[0] = 10; 119         var qr = RSAUtils.biDivideModulo(x, b); 120         var result = String(qr[1].digits[0]); 121         while (RSAUtils.biCompare(qr[0], bigZero) == 1) { 122             qr = RSAUtils.biDivideModulo(qr[0], b); 123             result += String(qr[1].digits[0]); 124  } 125         return (x.isNeg ? "-" : "") + RSAUtils.reverseStr(result); 126  }; 127 
128     var hexToChar = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 129         'a', 'b', 'c', 'd', 'e', 'f']; 130 
131     RSAUtils.digitToHex = function (n) { 132         var mask = 0xf; 133         var result = ""; 134         for (i = 0; i < 4; ++i) { 135             result += hexToChar[n & mask]; 136             n >>>= 4; 137  } 138         return RSAUtils.reverseStr(result); 139  }; 140 
141     RSAUtils.biToHex = function (x) { 142         var result = ""; 143         var n = RSAUtils.biHighIndex(x); 144         for (var i = RSAUtils.biHighIndex(x); i > -1; --i) { 145             result += RSAUtils.digitToHex(x.digits[i]); 146  } 147         return result; 148  }; 149 
150     RSAUtils.charToHex = function (c) { 151         var ZERO = 48; 152         var NINE = ZERO + 9; 153         var littleA = 97; 154         var littleZ = littleA + 25; 155         var bigA = 65; 156         var bigZ = 65 + 25; 157         var result; 158 
159         if (c >= ZERO && c <= NINE) { 160             result = c - ZERO; 161         } else if (c >= bigA && c <= bigZ) { 162             result = 10 + c - bigA; 163         } else if (c >= littleA && c <= littleZ) { 164             result = 10 + c - littleA; 165         } else { 166             result = 0; 167  } 168         return result; 169  }; 170 
171     RSAUtils.hexToDigit = function (s) { 172         var result = 0; 173         var sl = Math.min(s.length, 4); 174         for (var i = 0; i < sl; ++i) { 175             result <<= 4; 176             result |= RSAUtils.charToHex(s.charCodeAt(i)); 177  } 178         return result; 179  }; 180 
181     RSAUtils.biFromHex = function (s) { 182         var result = new BigInt(); 183         var sl = s.length; 184         for (var i = sl, j = 0; i > 0; i -= 4, ++j) { 185             result.digits[j] = RSAUtils.hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4))); 186  } 187         return result; 188  }; 189 
190     RSAUtils.biFromString = function (s, radix) { 191         var isNeg = s.charAt(0) == '-'; 192         var istop = isNeg ? 1 : 0; 193         var result = new BigInt(); 194         var place = new BigInt(); 195         place.digits[0] = 1; 196         for (var i = s.length - 1; i >= istop; i--) { 197             var c = s.charCodeAt(i); 198             var digit = RSAUtils.charToHex(c); 199             var biDigit = RSAUtils.biMultiplyDigit(place, digit); 200             result = RSAUtils.biAdd(result, biDigit); 201             place = RSAUtils.biMultiplyDigit(place, radix); 202  } 203         result.isNeg = isNeg; 204         return result; 205  }; 206 
207     RSAUtils.biDump = function (b) { 208         return (b.isNeg ? "-" : "") + b.digits.join(" "); 209  }; 210 
211     RSAUtils.biAdd = function (x, y) { 212         var result; 213 
214         if (x.isNeg != y.isNeg) { 215             y.isNeg = !y.isNeg; 216             result = RSAUtils.biSubtract(x, y); 217             y.isNeg = !y.isNeg; 218         } else { 219             result = new BigInt(); 220             var c = 0; 221             var n; 222             for (var i = 0; i < x.digits.length; ++i) { 223                 n = x.digits[i] + y.digits[i] + c; 224                 result.digits[i] = n % biRadix; 225                 c = Number(n >= biRadix); 226  } 227             result.isNeg = x.isNeg; 228  } 229         return result; 230  }; 231 
232     RSAUtils.biSubtract = function (x, y) { 233         var result; 234         if (x.isNeg != y.isNeg) { 235             y.isNeg = !y.isNeg; 236             result = RSAUtils.biAdd(x, y); 237             y.isNeg = !y.isNeg; 238         } else { 239             result = new BigInt(); 240             var n, c; 241             c = 0; 242             for (var i = 0; i < x.digits.length; ++i) { 243                 n = x.digits[i] - y.digits[i] + c; 244                 result.digits[i] = n % biRadix; 245 
246                 if (result.digits[i] < 0) result.digits[i] += biRadix; 247                 c = 0 - Number(n < 0); 248  } 249 
250             if (c == -1) { 251                 c = 0; 252                 for (var i = 0; i < x.digits.length; ++i) { 253                     n = 0 - result.digits[i] + c; 254                     result.digits[i] = n % biRadix; 255 
256                     if (result.digits[i] < 0) result.digits[i] += biRadix; 257                     c = 0 - Number(n < 0); 258  } 259 
260                 result.isNeg = !x.isNeg; 261             } else { 262 
263                 result.isNeg = x.isNeg; 264  } 265  } 266         return result; 267  }; 268 
269     RSAUtils.biHighIndex = function (x) { 270         var result = x.digits.length - 1; 271         while (result > 0 && x.digits[result] == 0) --result; 272         return result; 273  }; 274 
275     RSAUtils.biNumBits = function (x) { 276         var n = RSAUtils.biHighIndex(x); 277         var d = x.digits[n]; 278         var m = (n + 1) * bitsPerDigit; 279         var result; 280         for (result = m; result > m - bitsPerDigit; --result) { 281             if ((d & 0x8000) != 0) break; 282             d <<= 1; 283  } 284         return result; 285  }; 286 
287     RSAUtils.biMultiply = function (x, y) { 288         var result = new BigInt(); 289         var c; 290         var n = RSAUtils.biHighIndex(x); 291         var t = RSAUtils.biHighIndex(y); 292         var u, uv, k; 293 
294         for (var i = 0; i <= t; ++i) { 295             c = 0; 296             k = i; 297             for (j = 0; j <= n; ++j, ++k) { 298                 uv = result.digits[k] + x.digits[j] * y.digits[i] + c; 299                 result.digits[k] = uv & maxDigitVal; 300                 c = uv >>> biRadixBits; 301 
302  } 303             result.digits[i + n + 1] = c; 304  } 305 
306         result.isNeg = x.isNeg != y.isNeg; 307         return result; 308  }; 309 
310     RSAUtils.biMultiplyDigit = function (x, y) { 311         var n, c, uv; 312 
313         result = new BigInt(); 314         n = RSAUtils.biHighIndex(x); 315         c = 0; 316         for (var j = 0; j <= n; ++j) { 317             uv = result.digits[j] + x.digits[j] * y + c; 318             result.digits[j] = uv & maxDigitVal; 319             c = uv >>> biRadixBits; 320 
321  } 322         result.digits[1 + n] = c; 323         return result; 324  }; 325 
326     RSAUtils.arrayCopy = function (src, srcStart, dest, destStart, n) { 327         var m = Math.min(srcStart + n, src.length); 328         for (var i = srcStart, j = destStart; i < m; ++i, ++j) { 329             dest[j] = src[i]; 330  } 331  }; 332 
333     var highBitMasks = [0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 334         0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0, 335         0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF]; 336 
337     RSAUtils.biShiftLeft = function (x, n) { 338         var digitCount = Math.floor(n / bitsPerDigit); 339         var result = new BigInt(); 340         RSAUtils.arrayCopy(x.digits, 0, result.digits, digitCount, 341             result.digits.length - digitCount); 342         var bits = n % bitsPerDigit; 343         var rightBits = bitsPerDigit - bits; 344         for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) { 345             result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) |
346                 ((result.digits[i1] & highBitMasks[bits]) >>>
347  (rightBits)); 348  } 349         result.digits[0] = ((result.digits[i] << bits) & maxDigitVal); 350         result.isNeg = x.isNeg; 351         return result; 352  }; 353 
354     var lowBitMasks = [0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 355         0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 356         0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF]; 357 
358     RSAUtils.biShiftRight = function (x, n) { 359         var digitCount = Math.floor(n / bitsPerDigit); 360         var result = new BigInt(); 361         RSAUtils.arrayCopy(x.digits, digitCount, result.digits, 0, 362             x.digits.length - digitCount); 363         var bits = n % bitsPerDigit; 364         var leftBits = bitsPerDigit - bits; 365         for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) { 366             result.digits[i] = (result.digits[i] >>> bits) |
367                 ((result.digits[i1] & lowBitMasks[bits]) << leftBits); 368  } 369         result.digits[result.digits.length - 1] >>>= bits; 370         result.isNeg = x.isNeg; 371         return result; 372  }; 373 
374     RSAUtils.biMultiplyByRadixPower = function (x, n) { 375         var result = new BigInt(); 376         RSAUtils.arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n); 377         return result; 378  }; 379 
380     RSAUtils.biDivideByRadixPower = function (x, n) { 381         var result = new BigInt(); 382         RSAUtils.arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n); 383         return result; 384  }; 385 
386     RSAUtils.biModuloByRadixPower = function (x, n) { 387         var result = new BigInt(); 388         RSAUtils.arrayCopy(x.digits, 0, result.digits, 0, n); 389         return result; 390  }; 391 
392     RSAUtils.biCompare = function (x, y) { 393         if (x.isNeg != y.isNeg) { 394             return 1 - 2 * Number(x.isNeg); 395  } 396         for (var i = x.digits.length - 1; i >= 0; --i) { 397             if (x.digits[i] != y.digits[i]) { 398                 if (x.isNeg) { 399                     return 1 - 2 * Number(x.digits[i] > y.digits[i]); 400                 } else { 401                     return 1 - 2 * Number(x.digits[i] < y.digits[i]); 402  } 403  } 404  } 405         return 0; 406  }; 407 
408     RSAUtils.biDivideModulo = function (x, y) { 409         var nb = RSAUtils.biNumBits(x); 410         var tb = RSAUtils.biNumBits(y); 411         var origYIsNeg = y.isNeg; 412         var q, r; 413         if (nb < tb) { 414 
415             if (x.isNeg) { 416                 q = RSAUtils.biCopy(bigOne); 417                 q.isNeg = !y.isNeg; 418                 x.isNeg = false; 419                 y.isNeg = false; 420                 r = biSubtract(y, x); 421 
422                 x.isNeg = true; 423                 y.isNeg = origYIsNeg; 424             } else { 425                 q = new BigInt(); 426                 r = RSAUtils.biCopy(x); 427  } 428             return [q, r]; 429  } 430 
431         q = new BigInt(); 432         r = x; 433 
434 
435         var t = Math.ceil(tb / bitsPerDigit) - 1; 436         var lambda = 0; 437         while (y.digits[t] < biHalfRadix) { 438             y = RSAUtils.biShiftLeft(y, 1); 439             ++lambda; 440             ++tb; 441             t = Math.ceil(tb / bitsPerDigit) - 1; 442  } 443 
444 
445         r = RSAUtils.biShiftLeft(r, lambda); 446         nb += lambda; 447         var n = Math.ceil(nb / bitsPerDigit) - 1; 448 
449         var b = RSAUtils.biMultiplyByRadixPower(y, n - t); 450         while (RSAUtils.biCompare(r, b) != -1) { 451             ++q.digits[n - t]; 452             r = RSAUtils.biSubtract(r, b); 453  } 454         for (var i = n; i > t; --i) { 455             var ri = (i >= r.digits.length) ? 0 : r.digits[i]; 456             var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1]; 457             var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2]; 458             var yt = (t >= y.digits.length) ? 0 : y.digits[t]; 459             var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1]; 460             if (ri == yt) { 461                 q.digits[i - t - 1] = maxDigitVal; 462             } else { 463                 q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt); 464  } 465 
466             var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1); 467             var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2); 468             while (c1 > c2) { 469                 --q.digits[i - t - 1]; 470                 c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1); 471                 c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2); 472  } 473 
474             b = RSAUtils.biMultiplyByRadixPower(y, i - t - 1); 475             r = RSAUtils.biSubtract(r, RSAUtils.biMultiplyDigit(b, q.digits[i - t - 1])); 476             if (r.isNeg) { 477                 r = RSAUtils.biAdd(r, b); 478                 --q.digits[i - t - 1]; 479  } 480  } 481         r = RSAUtils.biShiftRight(r, lambda); 482 
483         q.isNeg = x.isNeg != origYIsNeg; 484         if (x.isNeg) { 485             if (origYIsNeg) { 486                 q = RSAUtils.biAdd(q, bigOne); 487             } else { 488                 q = RSAUtils.biSubtract(q, bigOne); 489  } 490             y = RSAUtils.biShiftRight(y, lambda); 491             r = RSAUtils.biSubtract(y, r); 492  } 493 
494         if (r.digits[0] == 0 && RSAUtils.biHighIndex(r) == 0) r.isNeg = false; 495 
496         return [q, r]; 497  }; 498 
499     RSAUtils.biDivide = function (x, y) { 500         return RSAUtils.biDivideModulo(x, y)[0]; 501  }; 502 
503     RSAUtils.biModulo = function (x, y) { 504         return RSAUtils.biDivideModulo(x, y)[1]; 505  }; 506 
507     RSAUtils.biMultiplyMod = function (x, y, m) { 508         return RSAUtils.biModulo(RSAUtils.biMultiply(x, y), m); 509  }; 510 
511     RSAUtils.biPow = function (x, y) { 512         var result = bigOne; 513         var a = x; 514         while (true) { 515             if ((y & 1) != 0) result = RSAUtils.biMultiply(result, a); 516             y >>= 1; 517             if (y == 0) break; 518             a = RSAUtils.biMultiply(a, a); 519  } 520         return result; 521  }; 522 
523     RSAUtils.biPowMod = function (x, y, m) { 524         var result = bigOne; 525         var a = x; 526         var k = y; 527         while (true) { 528             if ((k.digits[0] & 1) != 0) result = RSAUtils.biMultiplyMod(result, a, m); 529             k = RSAUtils.biShiftRight(k, 1); 530             if (k.digits[0] == 0 && RSAUtils.biHighIndex(k) == 0) break; 531             a = RSAUtils.biMultiplyMod(a, a, m); 532  } 533         return result; 534  }; 535 
536 
537     $w.BarrettMu = function (m) { 538         this.modulus = RSAUtils.biCopy(m); 539         this.k = RSAUtils.biHighIndex(this.modulus) + 1; 540         var b2k = new BigInt(); 541         b2k.digits[2 * this.k] = 1; 542         this.mu = RSAUtils.biDivide(b2k, this.modulus); 543         this.bkplus1 = new BigInt(); 544         this.bkplus1.digits[this.k + 1] = 1; 545         this.modulo = BarrettMu_modulo; 546         this.multiplyMod = BarrettMu_multiplyMod; 547         this.powMod = BarrettMu_powMod; 548  }; 549 
550     function BarrettMu_modulo(x) { 551         var $dmath = RSAUtils; 552         var q1 = $dmath.biDivideByRadixPower(x, this.k - 1); 553         var q2 = $dmath.biMultiply(q1, this.mu); 554         var q3 = $dmath.biDivideByRadixPower(q2, this.k + 1); 555         var r1 = $dmath.biModuloByRadixPower(x, this.k + 1); 556         var r2term = $dmath.biMultiply(q3, this.modulus); 557         var r2 = $dmath.biModuloByRadixPower(r2term, this.k + 1); 558         var r = $dmath.biSubtract(r1, r2); 559         if (r.isNeg) { 560             r = $dmath.biAdd(r, this.bkplus1); 561  } 562         var rgtem = $dmath.biCompare(r, this.modulus) >= 0; 563         while (rgtem) { 564             r = $dmath.biSubtract(r, this.modulus); 565             rgtem = $dmath.biCompare(r, this.modulus) >= 0; 566  } 567         return r; 568  } 569 
570     function BarrettMu_multiplyMod(x, y) { 571 
572         var xy = RSAUtils.biMultiply(x, y); 573         return this.modulo(xy); 574  } 575 
576     function BarrettMu_powMod(x, y) { 577         var result = new BigInt(); 578         result.digits[0] = 1; 579         var a = x; 580         var k = y; 581         while (true) { 582             if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a); 583             k = RSAUtils.biShiftRight(k, 1); 584             if (k.digits[0] == 0 && RSAUtils.biHighIndex(k) == 0) break; 585             a = this.multiplyMod(a, a); 586  } 587         return result; 588  } 589 
590     var RSAKeyPair = function (encryptionExponent, decryptionExponent, modulus) { 591         var $dmath = RSAUtils; 592         this.e = $dmath.biFromHex(encryptionExponent); 593         this.d = $dmath.biFromHex(decryptionExponent); 594         this.m = $dmath.biFromHex(modulus); 595 
596 
597         this.chunkSize = 2 * $dmath.biHighIndex(this.m); 598         this.radix = 16; 599         this.barrett = new $w.BarrettMu(this.m); 600  }; 601 
602     RSAUtils.getKeyPair = function (encryptionExponent, decryptionExponent, modulus) { 603         return new RSAKeyPair(encryptionExponent, decryptionExponent, modulus); 604  }; 605 
606     if (typeof $w.twoDigit === 'undefined') { 607         $w.twoDigit = function (n) { 608             return (n < 10 ? "0" : "") + String(n); 609  }; 610  } 611 
612 
613     RSAUtils.encryptedString = function (key, s) { 614         var a = []; 615         var sl = s.length; 616         var i = 0; 617         while (i < sl) { 618             a[i] = s.charCodeAt(i); 619             i++; 620  } 621 
622         while (a.length % key.chunkSize != 0) { 623             a[i++] = 0; 624  } 625 
626         var al = a.length; 627         var result = ""; 628         var j, k, block; 629         for (i = 0; i < al; i += key.chunkSize) { 630             block = new BigInt(); 631             j = 0; 632             for (k = i; k < i + key.chunkSize; ++j) { 633                 block.digits[j] = a[k++]; 634                 block.digits[j] += a[k++] << 8; 635  } 636             var crypt = key.barrett.powMod(block, key.e); 637             var text = key.radix == 16 ? RSAUtils.biToHex(crypt) : RSAUtils.biToString(crypt, key.radix); 638             result += text + " "; 639  } 640         return result.substring(0, result.length - 1); 641  }; 642 
643     RSAUtils.decryptedString = function (key, s) { 644         var blocks = s.split(" "); 645         var result = ""; 646         var i, j, block; 647         for (i = 0; i < blocks.length; ++i) { 648             var bi; 649             if (key.radix == 16) { 650                 bi = RSAUtils.biFromHex(blocks[i]); 651             } else { 652                 bi = RSAUtils.biFromString(blocks[i], key.radix); 653  } 654             block = key.barrett.powMod(bi, key.d); 655             for (j = 0; j <= RSAUtils.biHighIndex(block); ++j) { 656                 result += String.fromCharCode(block.digits[j] & 255, 657                     block.digits[j] >> 8); 658  } 659  } 660 
661         if (result.charCodeAt(result.length - 1) == 0) { 662             result = result.substring(0, result.length - 1); 663  } 664         return result; 665  }; 666 
667     RSAUtils.setMaxDigits(130); 668 
669 })(window);
View Code

2.login.jsp

將公鑰指數和公鑰係數從後臺controller傳過來接收後存入input並隱藏前端

<%--公鑰係數:--%>
<input type="hidden" id="hid_modulus" value="${pkModulus}"/>
<%--公鑰指數:--%>
<input type="hidden" id="hid_exponent" value="${pkExponent}"/>

引入rsasecurity.jsjava

<%--引入RSA非對稱加密js--%>
<script src="<%=basePath%>/plug-in/ace/js/rsasecurity.js"></script>

js代碼塊進行加密並傳到後臺git

var data = $(":input").each(function() { if (this.name == 'password') { //只加密密碼
        //獲取公鑰係數
        var modulus = $('#hid_modulus').val(); //獲取公鑰指數
        var exponent = $('#hid_exponent').val(); //獲取最終公鑰
        var key = RSAUtils.getKeyPair(exponent, '', modulus); //獲取需加密的值
        var passwordVal = $("#" + this.name).val(); //進行數據加密
        var ap = RSAUtils.encryptedString(key, encodeURI(passwordVal)); formData[this.name] = ap; } else { formData[this.name] = $("#" + this.name).val(); } }); $.ajax({ async: false, cache: false, type: 'POST', url: checkurl,// 請求的action路徑
 data: formData, error: function () {// 請求失敗處理函數
 }, success: function (data) { var d = $.parseJSON(data); if (d.success) { window.location.href = actionurl; } else { showErrorMsg(d.msg); } } });

3.LoginController.java

返回登陸視圖時即把公鑰係數和公鑰指數存入request域用於前臺接收web

// 獲取公鑰係數和公鑰指數 //獲取公鑰對象--注意:前端那邊須要用到公鑰係數和指數
RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey(); //公鑰-係數(n)
System.out.println("public key modulus:" + new String(Hex.encode(publicKey.getModulus().toByteArray()))); request.setAttribute("pkModulus", new String(Hex.encode(publicKey.getModulus().toByteArray()))); //公鑰-指數(e1)
System.out.println("public key exponent:" + new String(Hex.encode(publicKey.getPublicExponent().toByteArray()))); request.setAttribute("pkExponent", new String(Hex.encode(publicKey.getPublicExponent().toByteArray())));

前臺提交ajax請求進行登陸參數校驗時, 將js加密後的password進行解密(以後的校驗就不貼了)ajax

String userName = null; String password = null; try { userName = req.getParameter("userName"); password = req.getParameter("password"); password = RSAUtils.decryptStringByJs(password);//解密後的字符串
} catch (Exception e) { j.setSuccess(false); j.setMsg("用戶名或密碼錯誤!"); sendMessage(userName, "用戶名或密碼錯誤,登陸失敗!"); return j; }

4.RSAUtils.java

package org.jeecgframework.web.system.util; import org.apache.commons.lang3.StringUtils; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.encoders.Hex; import javax.crypto.Cipher; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.net.URLDecoder; import java.net.URLEncoder; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; /** * RSA算法加密/解密工具類。 * 如下代碼能夠使用,惟一須要注意的是: org.bouncycastle...這個jar包須要找一到放到項目中,RSA所需jar包在java中已經自帶了. * * @author liuyan */
public class RSAUtils { /** * 算法名稱 */
    private static final String ALGORITHOM = "RSA"; /** * 密鑰大小 */
    private static final int KEY_SIZE = 1024; /** * 默認的安全服務提供者 */
    private static final Provider DEFAULT_PROVIDER = new BouncyCastleProvider(); private static KeyPairGenerator keyPairGen = null; private static KeyFactory keyFactory = null; /** * 緩存的密鑰對。 */
    private static KeyPair oneKeyPair = null; //密文種子, 當想更換RSA鑰匙的時候,只須要修改密文種子,便可更換
    private static final String radamKey = "nari";//你本身隨便寫上數字或者英文便可 //類加載後進行初始化數據
    static { try { keyPairGen = KeyPairGenerator.getInstance(ALGORITHOM, DEFAULT_PROVIDER); keyFactory = KeyFactory.getInstance(ALGORITHOM, DEFAULT_PROVIDER); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); } } /** * 根據指定的密文種子,生成並返回RSA密鑰對。 */
    private static synchronized KeyPair generateKeyPair() { try { keyPairGen.initialize(KEY_SIZE, new SecureRandom(radamKey.getBytes())); oneKeyPair = keyPairGen.generateKeyPair(); return oneKeyPair; } catch (InvalidParameterException ex) { ex.printStackTrace(); } catch (NullPointerException ex) { ex.printStackTrace(); } return null; } /** * 返回初始化時默認的公鑰。 */
    public static RSAPublicKey getDefaultPublicKey() { KeyPair keyPair = generateKeyPair(); if (keyPair != null) { return (RSAPublicKey) keyPair.getPublic(); } return null; } /** * 使用指定的私鑰解密數據。 * * @param privateKey 給定的私鑰。 * @param data 要解密的數據。 * @return 原數據。 */
    public static byte[] decrypt(PrivateKey privateKey, byte[] data) throws Exception { Cipher ci = Cipher.getInstance(ALGORITHOM, DEFAULT_PROVIDER); ci.init(Cipher.DECRYPT_MODE, privateKey); return ci.doFinal(data); } /** * 使用默認的私鑰解密給定的字符串。 * * @param encryptText 密文。 * @return 原文字符串。 */
    public static String decryptString(String encryptText) { if (StringUtils.isBlank(encryptText)) { return null; } KeyPair keyPair = generateKeyPair(); try { byte[] en_data = Hex.decode(encryptText); byte[] data = decrypt((RSAPrivateKey) keyPair.getPrivate(), en_data); return new String(data); } catch (NullPointerException ex) { ex.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); } return null; } /** * 使用祕鑰 - 對js端傳遞過來密文進行解密 * * @param encryptText 密文。 * @return {@code encryptText} 的原文字符串。 */
    public static String decryptStringByJs(String encryptText) { String text = decryptString(encryptText); if (text == null) { return null; } String reverse = StringUtils.reverse(text); String decode = null; try { //這裏須要進行編碼轉換.注:在前端js對明文加密前須要先進行轉碼-可自行百度"編碼轉換"
            decode = URLDecoder.decode(reverse, "UTF-8"); System.out.println("解密後文字:" + decode); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return decode; } //java端 - 使用公鑰進行加密
    public static byte[] encrypt(String plaintext) throws Exception { // 獲取公鑰及參數e,n
        RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey(); //獲取公鑰指數 e
        BigInteger e = publicKey.getPublicExponent(); //獲取公鑰係數 n
        BigInteger n = publicKey.getModulus(); //先將明文進行編碼
        String encode = URLEncoder.encode(plaintext); // 獲取明文字節數組 m
        BigInteger m = new BigInteger(encode.getBytes()); // 進行明文加密 c
        BigInteger c = m.modPow(e, n); //返回密文字節數組
        return c.toByteArray(); } //java端 - 使用私鑰進行解密
    public static String decrypt(byte[] cipherText) throws Exception { // 讀取私鑰
        KeyPair keyPair = generateKeyPair(); RSAPrivateKey prk = (RSAPrivateKey) keyPair.getPrivate(); // 獲取私鑰參數-指數/係數
        BigInteger d = prk.getPrivateExponent(); BigInteger n = prk.getModulus(); // 讀取密文
        BigInteger c = new BigInteger(cipherText); // 進行解密
        BigInteger m = c.modPow(d, n); // 解密結果-字節數組
        byte[] mt = m.toByteArray(); //轉成String,此時是亂碼
        String en = new String(mt); //再進行編碼
        String result = URLDecoder.decode(en, "UTF-8"); //最後返回解密後獲得的明文
        return result; } public static void main(String[] args) { /*解密js端傳遞過來的密文*/
        //獲取公鑰對象--注意:前端那邊須要用到公鑰係數和指數
        RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey(); //公鑰-係數(n)
        System.out.println("public key modulus:" + new String(Hex.encode(publicKey.getModulus().toByteArray()))); //公鑰-指數(e1)
        System.out.println("public key exponent:" + new String(Hex.encode(publicKey.getPublicExponent().toByteArray()))); //JS加密後的字符串
        String param = "abd87309c1c01f8eb20e46008e7260d792b336505cccf6e0328a3b35f72ba6cec6f4913aa80e150f3f78529ef8259d04f8fb0cda049e1426b89e2122fae2470039556364cdde128bd1d9068ade1c828172086bc316907b77fe9551edfd0a7e427ecf310f720ee558bc1fee07714401554b0887672053ed9879f6aa895816f368"; //解密後的字符串
        String param1 = RSAUtils.decryptStringByJs(param); System.out.println(param1);
 } }

 貼一下公鑰係數和公鑰指數以及加密後的字符串(明文是123456)算法

公鑰係數: 00e0ffbc04ee1c099b3e898359a12a3d1a307415ec3daaff86e3d1b61a7d434e5073de79bc7de12324d4643fb93923f007897c35b7bb98c2864b8e4d319a5028935f882fad6ba1df8181478a331cf7d59335a603262bf7ad5aa648869ebd348640ad95f389eb603b6e301ea3e7aff24dc58209c2eef449a2bbe8d6d2159cdf1383 公鑰指數: 010001 js加密後的字符串: abd87309c1c01f8eb20e46008e7260d792b336505cccf6e0328a3b35f72ba6cec6f4913aa80e150f3f78529ef8259d04f8fb0cda049e1426b89e2122fae2470039556364cdde128bd1d9068ade1c828172086bc316907b77fe9551edfd0a7e427ecf310f720ee558bc1fee07714401554b0887672053ed9879f6aa895816f368

 

RSA後臺簽名前臺驗籤的應用(前臺採用jsrsasign庫)

關於後臺簽名前臺驗籤的, 若是有須要能夠參考:RSA前臺加密後臺解密的應用apache

感謝

相關文章
相關標籤/搜索