zoukankan      html  css  js  c++  java
  • RSA前台加密后台解密的应用

    写在前面

    项目安全测试需要将登录功能修改, AES加密不符合要求, 现改为RSA非对称加密.(将登录密码加密后传给后台, 后台解密后再进行一系列的校验) .期间遇到了前台js加密但是后台解密失败的问题https://www.cnblogs.com/yadongliang/p/11638995.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.js

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

    js代码块进行加密并传到后台

    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域用于前台接收

    // 获取公钥系数和公钥指数
    //获取公钥对象--注意:前端那边需要用到公钥系数和指数
    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进行解密(之后的校验就不贴了)

    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前台加密后台解密的应用

    感谢

  • 相关阅读:
    Java实现 洛谷 P1060 开心的金明
    (Java实现) 洛谷 P1605 迷宫
    (Java实现) 洛谷 P1605 迷宫
    (Java实现)洛谷 P1093 奖学金
    (Java实现)洛谷 P1093 奖学金
    Java实现 洛谷 P1064 金明的预算方案
    Java实现 洛谷 P1064 金明的预算方案
    (Java实现) 洛谷 P1031 均分纸牌
    QT树莓派交叉编译环开发环境搭建(附多个exe工具下载链接)
    武则天红人对唐睿宗的桃色报复(如此缺少城府,注定了要在宫廷中过早地出局)
  • 原文地址:https://www.cnblogs.com/yadongliang/p/11639763.html
Copyright © 2011-2022 走看看