写在前面

项目安全测试需要将登录功能修改, AES加密不符合要求, 现改为RSA非对称加密.(将登录密码加密后传给后台, 后台解密后再进行一系列的校验) .期间遇到了前台js加密但是后台解密失败的问题https://www.cnblogs.com/yadongliang/p/11638995.html, 下面是看了另一篇博客后正常加解密的步骤及关键代码.

步骤及关键代码

0.pom.xml

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

2.login.jsp

将公钥指数和公钥系数从后台controller传过来接收后存入input并隐藏

  1. <%--公钥系数:--%>
  2. <input type="hidden" id="hid_modulus" value="${pkModulus}"/>
  3. <%--公钥指数:--%>
  4. <input type="hidden" id="hid_exponent" value="${pkExponent}"/>

引入rsasecurity.js

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

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

  1. var data = $(":input").each(function() {
  2. if (this.name == 'password') { //只加密密码
  3. //获取公钥系数
  4. var modulus = $('#hid_modulus').val();
  5. //获取公钥指数
  6. var exponent = $('#hid_exponent').val();
  7. //获取最终公钥
  8. var key = RSAUtils.getKeyPair(exponent, '', modulus);
  9. //获取需加密的值
  10. var passwordVal = $("#" + this.name).val();
  11. //进行数据加密
  12. var ap = RSAUtils.encryptedString(key, encodeURI(passwordVal));
  13. formData[this.name] = ap;
  14. } else {
  15. formData[this.name] = $("#" + this.name).val();
  16. }
  17. });
  18.  
  19. $.ajax({
  20. async: false,
  21. cache: false,
  22. type: 'POST',
  23. url: checkurl,// 请求的action路径
  24. data: formData,
  25. error: function () {// 请求失败处理函数
  26. },
  27. success: function (data) {
  28. var d = $.parseJSON(data);
  29. if (d.success) {
  30. window.location.href = actionurl;
  31. } else {
  32. showErrorMsg(d.msg);
  33. }
  34. }
  35. });

3.LoginController.java

返回登录视图时即把公钥系数和公钥指数存入request域用于前台接收

  1. // 获取公钥系数和公钥指数
  2. //获取公钥对象--注意:前端那边需要用到公钥系数和指数
  3. RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey();
  4. //公钥-系数(n)
  5. System.out.println("public key modulus:" + new String(Hex.encode(publicKey.getModulus().toByteArray())));
  6. request.setAttribute("pkModulus", new String(Hex.encode(publicKey.getModulus().toByteArray())));
  7. //公钥-指数(e1)
  8. System.out.println("public key exponent:" + new String(Hex.encode(publicKey.getPublicExponent().toByteArray())));
  9. request.setAttribute("pkExponent", new String(Hex.encode(publicKey.getPublicExponent().toByteArray())));

前台提交ajax请求进行登录参数校验时, 将js加密后的password进行解密(之后的校验就不贴了)

  1. String userName = null;
  2. String password = null;
  3. try {
  4. userName = req.getParameter("userName");
  5. password = req.getParameter("password");
  6. password = RSAUtils.decryptStringByJs(password);//解密后的字符串
  7. } catch (Exception e) {
  8. j.setSuccess(false);
  9. j.setMsg("用户名或密码错误!");
  10. sendMessage(userName, "用户名或密码错误,登录失败!");
  11. return j;
  12. }

4.RSAUtils.java

  1. package org.jeecgframework.web.system.util;
  2.  
  3. import org.apache.commons.lang3.StringUtils;
  4. import org.bouncycastle.jce.provider.BouncyCastleProvider;
  5. import org.bouncycastle.util.encoders.Hex;
  6.  
  7. import javax.crypto.Cipher;
  8. import java.io.UnsupportedEncodingException;
  9. import java.math.BigInteger;
  10. import java.net.URLDecoder;
  11. import java.net.URLEncoder;
  12. import java.security.*;
  13. import java.security.interfaces.RSAPrivateKey;
  14. import java.security.interfaces.RSAPublicKey;
  15.  
  16. /**
  17. * RSA算法加密/解密工具类。
  18. * 以下代码可以使用,唯一需要注意的是: org.bouncycastle...这个jar包需要找一到放到项目中,RSA所需jar包在java中已经自带了.
  19. *
  20. * @author liuyan
  21. */
  22. public class RSAUtils {
  23. /**
  24. * 算法名称
  25. */
  26. private static final String ALGORITHOM = "RSA";
  27. /**
  28. * 密钥大小
  29. */
  30. private static final int KEY_SIZE = 1024;
  31. /**
  32. * 默认的安全服务提供者
  33. */
  34. private static final Provider DEFAULT_PROVIDER = new BouncyCastleProvider();
  35. private static KeyPairGenerator keyPairGen = null;
  36. private static KeyFactory keyFactory = null;
  37. /**
  38. * 缓存的密钥对。
  39. */
  40. private static KeyPair oneKeyPair = null;
  41.  
  42. //密文种子, 当想更换RSA钥匙的时候,只需要修改密文种子,即可更换
  43. private static final String radamKey = "nari";//你自己随便写上数字或者英文即可
  44.  
  45. //类加载后进行初始化数据
  46. static {
  47. try {
  48. keyPairGen = KeyPairGenerator.getInstance(ALGORITHOM,
  49. DEFAULT_PROVIDER);
  50. keyFactory = KeyFactory.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
  51. } catch (NoSuchAlgorithmException ex) {
  52. ex.printStackTrace();
  53. }
  54. }
  55.  
  56. /**
  57. * 根据指定的密文种子,生成并返回RSA密钥对。
  58. */
  59. private static synchronized KeyPair generateKeyPair() {
  60. try {
  61. keyPairGen.initialize(KEY_SIZE,
  62. new SecureRandom(radamKey.getBytes()));
  63. oneKeyPair = keyPairGen.generateKeyPair();
  64. return oneKeyPair;
  65. } catch (InvalidParameterException ex) {
  66. ex.printStackTrace();
  67. } catch (NullPointerException ex) {
  68. ex.printStackTrace();
  69. }
  70. return null;
  71. }
  72.  
  73. /**
  74. * 返回初始化时默认的公钥。
  75. */
  76. public static RSAPublicKey getDefaultPublicKey() {
  77. KeyPair keyPair = generateKeyPair();
  78. if (keyPair != null) {
  79. return (RSAPublicKey) keyPair.getPublic();
  80. }
  81. return null;
  82. }
  83.  
  84. /**
  85. * 使用指定的私钥解密数据。
  86. *
  87. * @param privateKey 给定的私钥。
  88. * @param data 要解密的数据。
  89. * @return 原数据。
  90. */
  91. public static byte[] decrypt(PrivateKey privateKey, byte[] data) throws Exception {
  92. Cipher ci = Cipher.getInstance(ALGORITHOM, DEFAULT_PROVIDER);
  93. ci.init(Cipher.DECRYPT_MODE, privateKey);
  94. return ci.doFinal(data);
  95. }
  96.  
  97. /**
  98. * 使用默认的私钥解密给定的字符串。
  99. *
  100. * @param encryptText 密文。
  101. * @return 原文字符串。
  102. */
  103. public static String decryptString(String encryptText) {
  104. if (StringUtils.isBlank(encryptText)) {
  105. return null;
  106. }
  107. KeyPair keyPair = generateKeyPair();
  108. try {
  109. byte[] en_data = Hex.decode(encryptText);
  110. byte[] data = decrypt((RSAPrivateKey) keyPair.getPrivate(), en_data);
  111. return new String(data);
  112. } catch (NullPointerException ex) {
  113. ex.printStackTrace();
  114. } catch (Exception ex) {
  115. ex.printStackTrace();
  116. }
  117. return null;
  118. }
  119.  
  120. /**
  121. * 使用秘钥 - 对js端传递过来密文进行解密
  122. *
  123. * @param encryptText 密文。
  124. * @return {@code encryptText} 的原文字符串。
  125. */
  126. public static String decryptStringByJs(String encryptText) {
  127. String text = decryptString(encryptText);
  128. if (text == null) {
  129. return null;
  130. }
  131. String reverse = StringUtils.reverse(text);
  132. String decode = null;
  133. try {
  134. //这里需要进行编码转换.注:在前端js对明文加密前需要先进行转码-可自行百度"编码转换"
  135. decode = URLDecoder.decode(reverse, "UTF-8");
  136. System.out.println("解密后文字:" + decode);
  137. } catch (UnsupportedEncodingException e) {
  138. e.printStackTrace();
  139. }
  140. return decode;
  141. }
  142.  
  143. //java端 - 使用公钥进行加密
  144. public static byte[] encrypt(String plaintext) throws Exception {
  145. // 获取公钥及参数e,n
  146. RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey();
  147. //获取公钥指数 e
  148. BigInteger e = publicKey.getPublicExponent();
  149. //获取公钥系数 n
  150. BigInteger n = publicKey.getModulus();
  151. //先将明文进行编码
  152. String encode = URLEncoder.encode(plaintext);
  153. // 获取明文字节数组 m
  154. BigInteger m = new BigInteger(encode.getBytes());
  155. // 进行明文加密 c
  156. BigInteger c = m.modPow(e, n);
  157. //返回密文字节数组
  158. return c.toByteArray();
  159. }
  160.  
  161. //java端 - 使用私钥进行解密
  162. public static String decrypt(byte[] cipherText) throws Exception {
  163. // 读取私钥
  164. KeyPair keyPair = generateKeyPair();
  165. RSAPrivateKey prk = (RSAPrivateKey) keyPair.getPrivate();
  166. // 获取私钥参数-指数/系数
  167. BigInteger d = prk.getPrivateExponent();
  168. BigInteger n = prk.getModulus();
  169. // 读取密文
  170. BigInteger c = new BigInteger(cipherText);
  171. // 进行解密
  172. BigInteger m = c.modPow(d, n);
  173. // 解密结果-字节数组
  174. byte[] mt = m.toByteArray();
  175. //转成String,此时是乱码
  176. String en = new String(mt);
  177. //再进行编码
  178. String result = URLDecoder.decode(en, "UTF-8");
  179. //最后返回解密后得到的明文
  180. return result;
  181. }
  182.  
  183. public static void main(String[] args) {
  184. /*解密js端传递过来的密文*/
  185. //获取公钥对象--注意:前端那边需要用到公钥系数和指数
  186. RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey();
  187. //公钥-系数(n)
  188. System.out.println("public key modulus:" + new String(Hex.encode(publicKey.getModulus().toByteArray())));
  189. //公钥-指数(e1)
  190. System.out.println("public key exponent:" + new String(Hex.encode(publicKey.getPublicExponent().toByteArray())));
  191. //JS加密后的字符串
  192. String param = "abd87309c1c01f8eb20e46008e7260d792b336505cccf6e0328a3b35f72ba6cec6f4913aa80e150f3f78529ef8259d04f8fb0cda049e1426b89e2122fae2470039556364cdde128bd1d9068ade1c828172086bc316907b77fe9551edfd0a7e427ecf310f720ee558bc1fee07714401554b0887672053ed9879f6aa895816f368";
  193. //解密后的字符串
  194. String param1 = RSAUtils.decryptStringByJs(param);
  195.  
  196. System.out.println(param1);
  197.  
  198. }
  199. }

贴一下公钥系数和公钥指数以及加密后的字符串(明文是123456)

  1. 公钥系数:
  2. 00e0ffbc04ee1c099b3e898359a12a3d1a307415ec3daaff86e3d1b61a7d434e5073de79bc7de12324d4643fb93923f007897c35b7bb98c2864b8e4d319a5028935f882fad6ba1df8181478a331cf7d59335a603262bf7ad5aa648869ebd348640ad95f389eb603b6e301ea3e7aff24dc58209c2eef449a2bbe8d6d2159cdf1383
  3.  
  4. 公钥指数:
  5. 010001
  6.  
  7. js加密后的字符串:
  8. abd87309c1c01f8eb20e46008e7260d792b336505cccf6e0328a3b35f72ba6cec6f4913aa80e150f3f78529ef8259d04f8fb0cda049e1426b89e2122fae2470039556364cdde128bd1d9068ade1c828172086bc316907b77fe9551edfd0a7e427ecf310f720ee558bc1fee07714401554b0887672053ed9879f6aa895816f368

RSA后台签名前台验签的应用(前台采用jsrsasign库)

关于后台签名前台验签的, 如果有需要可以参考:RSA前台加密后台解密的应用

感谢

RSA前台加密后台解密的应用的更多相关文章

  1. RSA前台加密后台解密

    RSA解密时BadPaddingException java rsa 解密报:javax.crypto.BadPaddingException: Decryption error Java安全架构__ ...

  2. aes前台加密后台解密

    aes加密npm地址:https://www.npmjs.com/package/crypto-js aes加密git地址/下载: https://github.com/brix/crypto-js ...

  3. asp.net MVC ajax 请求参数前台加密后台解密

    最近有一个需求要求页面查询数据库,查询内容保存到excel里面作为附件加密打包下载.查询的sql作为参数传入后台,实现加密提交.这里做个记录,后面用到直接来拿. 控制器 public ActionRe ...

  4. RSA 登陆加密与解密

    最近公司项目验收后,客户请来的信息安全技术人员对我们的网站进行了各种安全测试与排查问题,其中就有一个登陆时的加密问题.本来如果只是单纯的加密,可以直接在前台用MD5加密,将加密的值添加到数据库即可.但 ...

  5. 密码疑云 (3)——详解RSA的加密与解密

    上一篇文章介绍了RSA涉及的数学知识,本章将应用这些知识详解RSA的加密与解密. RSA算法的密钥生成过程 密钥的生成是RSA算法的核心,它的密钥对生成过程如下: 1. 选择两个不相等的大素数p和q, ...

  6. polarssl rsa & aes 加密与解密

    上周折腾加密与解密,用了openssl, crypto++, polarssl, cyassl, 说起真的让人很沮丧,只有openssl & polarssl两个库的RSA & AES ...

  7. polarssl rsa & aes 加密与解密<转>

    上周折腾加密与解密,用了openssl, crypto++, polarssl, cyassl, 说起真的让人很沮丧,只有openssl & polarssl两个库的RSA & AES ...

  8. 求求你们不要再用 RSA 私钥加密公钥解密了,这非常不安全!

    最近经常在网上看到有人说巨硬的 CNG(Cryptography Next Generation 即下一代加密技术) 只提供 RSA 公钥加密私钥解密,没有提供 RSA 私钥加密公钥解密,他们要自己封 ...

  9. RSA js加密 java解密

    1. 首先你要拥有一对公钥.私钥: ``` pubKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1gr+rIfYlaNUNLiFsK/Kn ...

随机推荐

  1. Java 之 日期时间类

    一.Date类 1.概述 java.util.Date 类 表示特定的瞬间,精确到毫秒. 2.构造方法 public Date():分配Date对象并初始化此对象,以表示分配它的时间(精确到毫秒) p ...

  2. k8s网络配置管理

    docker容器的四种网络类型 1.桥接           2.联盟    3.主机    4.无 docker跨节点的容器通信必须通过NAT机制  宿主机上的容器一般都是私网地址 它可以通过宿主机 ...

  3. Golang Web应用 创建docker镜像笔记(win 平台)

    记录的是 本地编译好了再创建容器镜像的方法 ,这样子生成的镜像文件比较小,方便分发部署 win 平台需要设置golang交叉编译 生成linux可执行文件 CMD下: Set GOOS="l ...

  4. java实现快速排序,归并排序

    //1.快速排序 import java.util.*; public class Main { public static void main(String[] args) { Scanner sc ...

  5. Centos 7 中的ulimit -n 65535 对进程的文件句柄限制不生效??

    今日闲来无事,就看群里大佬吹牛逼了,偶然一条技术疑问提出来了,神奇啊,作为广大老司机技术交流群体竟然还有这么深入的研究? 大佬问:这个文件句柄限制怎么设置了/etc/security/limits.c ...

  6. 【转载】自定义View学习笔记之详解onMeasure

    网上对自定义View总结的文章都很多,但是自己还是写一篇,好记性不如多敲字! 其实自定义View就是三大流程,onMeasure.onLayout.onDraw.看名字就知道,onMeasure是用来 ...

  7. springboot集成ftp

    目录 springboot集成ftp pom依赖包 ftp登录初始化 ftp上传文件 ftp读取文件,并转成base64 ftp下载文件 ftp客户端与服务端之间数据传输,主动模式和被动模式 spri ...

  8. 关于__int 128 的读入与输出

    inline __int128 read() { ,w=; ; while(!isdigit(ch)) {w|=ch=='-';ch=getchar();} )+(X<<)+(ch^),c ...

  9. react的优点:兼容了dsl语法与UI的组件化管理

    react的优点:兼容了dsl语法与UI的组件化管理. 组件化管理的dsl描述 UI: 虚拟dom:

  10. 严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener

    十月 30, 2019 11:12:35 下午 org.apache.catalina.core.StandardContext listenerStart 严重: Exception sending ...