在一次项目实战中,前端登录使用了RSA加密,使用LoadRunner压测的第一步,就是模拟用户登录,可惜loadRunner11并不能录制前端的加密过程,并且安装的LR是基于C语言版,网络上关于RSA的加密更多的是Java版,最后,选择在Jmeter中先尝试一下能否解决加密的问题,毕竟它有很多处理器,用于脚本的插入;

  把解决过程中遇到的问题,简单做个记录,防止遗忘,也算是给自己下一次项目一个经验总结了;

【1】了解加密方式-----RSA

  询问开发前端的加密方式:先请求public_key,再加密密码,再提交。

  加密的代码前端代码实现:

  $.getJSON('/public_key?t='+timestamp).then((rsa) => {

    let rsaKey = new RSAKey();

   rsaKey.setPublic(b64tohex(rsa.modulus), b64tohex(rsa.exponent));

   data.password = hex2b64(rsaKey.encrypt(data.password));

    $.post('/ajax_login_check', data).then(this.completed, this.failed);

  }, this.failed);

  备注:以上来自开发,后来在了解RSA的实现方式中,发现大家的RSA前端加密方式是一样的~

  已知了上面这些,下面开始自己玩前端RSA加密的方式,抓包查看登录的请求,有三个重要的请求:

  ①GET /public_key?t=1495537754854 :用于获取RAS生成公钥时的两个重要参数exponent 和 modulus;

  ②POST /ajax_login_check:用于将已加密的密码 && 登录名post到服务器去验证,验证成功后返回success;

  ③GET /:在 /ajax_login_check验证成功后,GET /请求会返回一个TOKEN值,作为该用户进入系统后的令牌,执行系统内的每一个操作时,对应的请求都需要在头部添加该参数,否则会报403错误;

【2】查找加密使用的js文件

  也是走了很多弯路,先在DOS下折腾,后又安装了eclipse,在网上找寻各种加密代码,打成jar包,在LoadRunner中却无法使用;将网上关于RSA的java类及方法直接放在Jmeter中进行加密,Jmeter连import都不支持;

  然后,仔细查看登录的每一个请求包,注意到一个js文件,其中有关于BigInteger和RSA的函数定义(C语言中是这样称呼的,我也这样称呼了),想一想既然是在前端加密,那服务器会不会直接将加密使用的方法返回给客户端呢,谷歌浏览器按“F12”查看登录页面的Sources,查找js文件,后来发现前面提到的js文件sec.min.js中竟然有开发用于加密的函数hex2b64(),急忙将该js文件保存在本地,开发使用到的加密的方法都可以在这个文件中找到,喜极而泣;

【3】使用Jmeter的JSR223后置处理器,完成加密

  使用apache-jmeter-2.12 + jdk 1.6,在JSR223中load("sec.min.js");,总是报错“jmeter.modifiers.JSR223PreProcessor: Problem in JSR223 script JSR223 PreProcessor javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "load" is not defined.”,后考虑是不是版本问题,换了apache-jmeter-3.2 + jdk1.8,load不再报错;

  注:①使用到的js文件需要放在jmeter的bin目录下;②JSR223中,Language选择“JavaScript”;

  Jmeter中加密的调用实现如下:

  JSR223中使用到的modules的正则表达式提取如下:

【4】调试js文件

  勾选Jmeter“选项”→“Log Viewer”,添加Debug后置处理器;在Jmeter中会打印代码执行的情况,有错误的话就逐步排除;PS:调试很艰难,且调且珍惜;

  ①navigator  报错,求助网络,这是浏览器对象,因为录制时使用的谷歌浏览器,所以我选择了保留关于谷歌的设置(其实不一定要选择谷歌相关的,只要js文件中使用同一浏览器的相关属性值即可),将不重要的直接可以注释掉,类似的还有 window;

   

 

  ②alert()在Jmeter中无法执行(会报错):直接将js中的alert()注释,并用return null; 替换,便于调试;

  ③我在调试过程中还遇到 toRadix & signum &  chunkSize & intValue未定义;继续使用F12查看自己是否有遗漏需要load的js文件,并没有找到,然后在网上搜索  toRadix 直接就出来了,O(∩_∩)O~~,于是添加属性及方法在js文件中,正确执行,耶耶耶~~~~链接:http://blog.csdn.net/huaye2007/article/details/41727921

【4】后续处理

  ①GET /public_key?t=1495537754854这里的t是Unix时间戳,在该请求中添加 JSR223前置处理器,使用如下语句完成处理:

  var timestamp=new Date().getTime();   //精确到毫秒;

  vars.put("timestamp",timestamp);

  ②依旧显示密码错误:一步步排查,注意到在POST时,“查看结果树”的“请求”中显示的内容与log中打印的不一致(密文为base64编码),具体为“+”显示不正确,再次询问网络,有人提到含有“+”的字符串在URL中传递时,需要替换加号为%2B,否则在服务器解码的时候会出错;

  后来勾选了 /ajax_login_check请求对应的参数“password”值的“编码”,在该请求的结果树中,可以看到POST的密文已经将“+”及“/”进行了转码,因此最终并未使用替换语句;

  附上替换语句:data = data.replace(/\+/g,"%2B");      data = data.replace(/\//g,"%2F");   // \g代表全部替换

  至此,完成了前端模拟RSA加密,进行登录,ajax校验用户名&密码通过;

  总结及感悟:对于前端加密,服务器应该是要返回加密方式给客户端的,否则客户端无从知晓如何加密,至于加密的方式是否可以直接识别,1在于服务端的返回内容,2在于测试人员是否有很好的观察及辨识能力,而这种辨识能力就在于平时的多涉猎多接触,一开始抓包也有看到sec.min.js,但是并没有敏锐的意识到加密就藏在这里,兜兜转转才发现,所以还是要多学习,开发知识也好,测试知识也罢O(∩_∩)O~~

  附1----------Jmeter中JSR前置处理器的javascript脚本

  1. load("sec.min.js");
  2.  
  3. var modulus = vars.get("modulus");
  4. log.info(modulus);
  5. var exponent = vars.get("exponent");
  6. log.info(exponent);
  7.  
  8. function RSA(){
  9. var rsaKey = new RSAKey();
  10. rsaKey.setPublic(b64tohex("${modulus}"),b64tohex("${exponent}"));
  11. var Enpassword = hex2b64(rsaKey.encrypt("${password}"));
  12. return Enpassword
  13. }
  14. var data = RSA();
  15. log.info(data);
  16. //base64在url中的传输,要注意+ /两个符号
  17. //data = data.replace(/\+/g,"%2B");
  18. //data = data.replace(/\//g,"%2F");
  19. vars.put("Password",data);
  1. var dbits;
  2. var canary = 244837814094590;
  3. var j_lm = ((canary & 16777215) == 15715070);
  4. function BigInteger(e, d, f) {
  5. if (e != null) {
  6. if ("number" == typeof e) {
  7. this.fromNumber(e, d, f)
  8. } else {
  9. if (d == null && "string" != typeof e) {
  10. this.fromString(e, 256)
  11. } else {
  12. this.fromString(e, d)
  13. }
  14. }
  15. }
  16. }
  17. function nbi() {
  18. return new BigInteger(null)
  19. }
  20. function am1(f, a, b, e, h, g) {
  21. while (--g >= 0) {
  22. var d = a * this[f++] + b[e] + h;
  23. h = Math.floor(d / 67108864);
  24. b[e++] = d & 67108863
  25. }
  26. return h
  27. }
  28. function am2(f, q, r, e, o, a) {
  29. var k = q & 32767,
  30. p = q >> 15;
  31. while (--a >= 0) {
  32. var d = this[f] & 32767;
  33. var g = this[f++] >> 15;
  34. var b = p * d + g * k;
  35. d = k * d + ((b & 32767) << 15) + r[e] + (o & 1073741823);
  36. o = (d >>> 30) + (b >>> 15) + p * g + (o >>> 30);
  37. r[e++] = d & 1073741823
  38. }
  39. return o
  40. }
  41. function am3(f, q, r, e, o, a) {
  42. var k = q & 16383,
  43. p = q >> 14;
  44. while (--a >= 0) {
  45. var d = this[f] & 16383;
  46. var g = this[f++] >> 14;
  47. var b = p * d + g * k;
  48. d = k * d + ((b & 16383) << 14) + r[e] + o;
  49. o = (d >> 28) + (b >> 14) + p * g;
  50. r[e++] = d & 268435455
  51. }
  52. return o
  53. }
  54. //if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) { //xpp注释
  55. // BigInteger.prototype.am = am2;
  56. // dbits = 30
  57. //} else {
  58. // if (j_lm && (navigator.appName != "Netscape")) {
  59. // BigInteger.prototype.am = am1;
  60. // dbits = 26
  61. // } else {
  62. BigInteger.prototype.am = am3;
  63. dbits = 28
  64. // }
  65. //}
  66. BigInteger.prototype.DB = dbits;
  67. BigInteger.prototype.DM = ((1 << dbits) - 1);
  68. BigInteger.prototype.DV = (1 << dbits);
  69. var BI_FP = 52;
  70. BigInteger.prototype.FV = Math.pow(2, BI_FP);
  71. BigInteger.prototype.F1 = BI_FP - dbits;
  72. BigInteger.prototype.F2 = 2 * dbits - BI_FP;
  73. var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
  74. var BI_RC = new Array();
  75. var rr, vv;
  76. rr = "0".charCodeAt(0);
  77. for (vv = 0; vv <= 9; ++vv) {
  78. BI_RC[rr++] = vv
  79. }
  80. rr = "a".charCodeAt(0);
  81. for (vv = 10; vv < 36; ++vv) {
  82. BI_RC[rr++] = vv
  83. }
  84. rr = "A".charCodeAt(0);
  85. for (vv = 10; vv < 36; ++vv) {
  86. BI_RC[rr++] = vv
  87. }
  88. function int2char(a) {
  89. return BI_RM.charAt(a)
  90. }
  91. function intAt(b, a) {
  92. var d = BI_RC[b.charCodeAt(a)];
  93. return (d == null) ? -1 : d
  94. }
  95. //-----摘自网络-----start
  96. function bnpToRadix(b) {
  97. if (b == null) {
  98. b = 10
  99. }
  100. if (this.signum() == 0 || b < 2 || b > 36) {
  101. return "0"
  102. }
  103. var cs = this.chunkSize(b);
  104. var a = Math.pow(b, cs);
  105. var d = nbv(a),
  106. y = nbi(),
  107. z = nbi(),
  108. r = "";
  109. this.divRemTo(d, y, z);
  110. while (y.signum() > 0) {
  111. r = (a + z.intValue()).toString(b).substr(1) + r;
  112. y.divRemTo(d, y, z)
  113. }
  114. return z.intValue().toString(b) + r
  115. }
  116. function bnSigNum() {
  117. if (this.s < 0) {
  118. return -1
  119. } else {
  120. if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) {
  121. return 0
  122. } else {
  123. return 1
  124. }
  125. }
  126. }
  127. function bnpChunkSize(r) {
  128. return Math.floor(Math.LN2 * this.DB / Math.log(r))
  129. }
  130. function bnIntValue() {
  131. if (this.s < 0) {
  132. if (this.t == 1) {
  133. return this[0] - this.DV
  134. } else {
  135. if (this.t == 0) {
  136. return -1
  137. }
  138. }
  139. } else {
  140. if (this.t == 1) {
  141. return this[0]
  142. } else {
  143. if (this.t == 0) {
  144. return 0
  145. }
  146. }
  147. }
  148. return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]
  149. }
  150. //-----摘自网络-----end
  151.  
  152. function bnpCopyTo(b) {
  153. for (var a = this.t - 1; a >= 0; --a) {
  154. b[a] = this[a]
  155. }
  156. b.t = this.t;
  157. b.s = this.s
  158. }
  159. function bnpFromInt(a) {
  160. this.t = 1;
  161. this.s = (a < 0) ? -1 : 0;
  162. if (a > 0) {
  163. this[0] = a
  164. } else {
  165. if (a < -1) {
  166. this[0] = a + DV
  167. } else {
  168. this.t = 0
  169. }
  170. }
  171. }
  172. function nbv(a) {
  173. var b = nbi();
  174. b.fromInt(a);
  175. return b
  176. }
  177. function bnpFromString(h, c) {
  178. var e;
  179. if (c == 16) {
  180. e = 4
  181. } else {
  182. if (c == 8) {
  183. e = 3
  184. } else {
  185. if (c == 256) {
  186. e = 8
  187. } else {
  188. if (c == 2) {
  189. e = 1
  190. } else {
  191. if (c == 32) {
  192. e = 5
  193. } else {
  194. if (c == 4) {
  195. e = 2
  196. } else {
  197. this.fromRadix(h, c);
  198. return
  199. }
  200. }
  201. }
  202. }
  203. }
  204. }
  205. this.t = 0;
  206. this.s = 0;
  207. var g = h.length,
  208. d = false,
  209. f = 0;
  210. while (--g >= 0) {
  211. var a = (e == 8) ? h[g] & 255 : intAt(h, g);
  212. if (a < 0) {
  213. if (h.charAt(g) == "-") {
  214. d = true
  215. }
  216. continue
  217. }
  218. d = false;
  219. if (f == 0) {
  220. this[this.t++] = a
  221. } else {
  222. if (f + e > this.DB) {
  223. this[this.t - 1] |= (a & ((1 << (this.DB - f)) - 1)) << f;
  224. this[this.t++] = (a >> (this.DB - f))
  225. } else {
  226. this[this.t - 1] |= a << f
  227. }
  228. }
  229. f += e;
  230. if (f >= this.DB) {
  231. f -= this.DB
  232. }
  233. }
  234. if (e == 8 && (h[0] & 128) != 0) {
  235. this.s = -1;
  236. if (f > 0) {
  237. this[this.t - 1] |= ((1 << (this.DB - f)) - 1) << f
  238. }
  239. }
  240. this.clamp();
  241. if (d) {
  242. BigInteger.ZERO.subTo(this, this)
  243. }
  244. }
  245. function bnpClamp() {
  246. var a = this.s & this.DM;
  247. while (this.t > 0 && this[this.t - 1] == a) {
  248. --this.t
  249. }
  250. }
  251. function bnToString(c) {
  252. if (this.s < 0) {
  253. return "-" + this.negate().toString(c)
  254. }
  255. var e;
  256. if (c == 16) {
  257. e = 4
  258. } else {
  259. if (c == 8) {
  260. e = 3
  261. } else {
  262. if (c == 2) {
  263. e = 1
  264. } else {
  265. if (c == 32) {
  266. e = 5
  267. } else {
  268. if (c == 4) {
  269. e = 2
  270. } else {
  271. return this.toRadix(c)
  272. }
  273. }
  274. }
  275. }
  276. }
  277. var g = (1 << e) - 1,
  278. l,
  279. a = false,
  280. h = "",
  281. f = this.t;
  282. var j = this.DB - (f * this.DB) % e;
  283. if (f-- > 0) {
  284. if (j < this.DB && (l = this[f] >> j) > 0) {
  285. a = true;
  286. h = int2char(l)
  287. }
  288. while (f >= 0) {
  289. if (j < e) {
  290. l = (this[f] & ((1 << j) - 1)) << (e - j);
  291. l |= this[--f] >> (j += this.DB - e)
  292. } else {
  293. l = (this[f] >> (j -= e)) & g;
  294. if (j <= 0) {
  295. j += this.DB;
  296. --f
  297. }
  298. }
  299. if (l > 0) {
  300. a = true
  301. }
  302. if (a) {
  303. h += int2char(l)
  304. }
  305. }
  306. }
  307. return a ? h : "0"
  308. }
  309. function bnNegate() {
  310. var a = nbi();
  311. BigInteger.ZERO.subTo(this, a);
  312. return a
  313. }
  314. function bnAbs() {
  315. return (this.s < 0) ? this.negate() : this
  316. }
  317. function bnCompareTo(b) {
  318. var d = this.s - b.s;
  319. if (d != 0) {
  320. return d
  321. }
  322. var c = this.t;
  323. d = c - b.t;
  324. if (d != 0) {
  325. return (this.s < 0) ? -d : d
  326. }
  327. while (--c >= 0) {
  328. if ((d = this[c] - b[c]) != 0) {
  329. return d
  330. }
  331. }
  332. return 0
  333. }
  334. function nbits(a) {
  335. var c = 1,
  336. b;
  337. if ((b = a >>> 16) != 0) {
  338. a = b;
  339. c += 16
  340. }
  341. if ((b = a >> 8) != 0) {
  342. a = b;
  343. c += 8
  344. }
  345. if ((b = a >> 4) != 0) {
  346. a = b;
  347. c += 4
  348. }
  349. if ((b = a >> 2) != 0) {
  350. a = b;
  351. c += 2
  352. }
  353. if ((b = a >> 1) != 0) {
  354. a = b;
  355. c += 1
  356. }
  357. return c
  358. }
  359. function bnBitLength() {
  360. if (this.t <= 0) {
  361. return 0
  362. }
  363. return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM))
  364. }
  365.  
  366. function bnpDLShiftTo(c, b) {
  367. var a;
  368. for (a = this.t - 1; a >= 0; --a) {
  369. b[a + c] = this[a]
  370. }
  371. for (a = c - 1; a >= 0; --a) {
  372. b[a] = 0
  373. }
  374. b.t = this.t + c;
  375. b.s = this.s
  376. }
  377. function bnpDRShiftTo(c, b) {
  378. for (var a = c; a < this.t; ++a) {
  379. b[a - c] = this[a]
  380. }
  381. b.t = Math.max(this.t - c, 0);
  382. b.s = this.s
  383. }
  384. function bnpLShiftTo(j, e) {
  385. var b = j % this.DB;
  386. var a = this.DB - b;
  387. var g = (1 << a) - 1;
  388. var f = Math.floor(j / this.DB),
  389. h = (this.s << b) & this.DM,
  390. d;
  391. for (d = this.t - 1; d >= 0; --d) {
  392. e[d + f + 1] = (this[d] >> a) | h;
  393. h = (this[d] & g) << b
  394. }
  395. for (d = f - 1; d >= 0; --d) {
  396. e[d] = 0
  397. }
  398. e[f] = h;
  399. e.t = this.t + f + 1;
  400. e.s = this.s;
  401. e.clamp()
  402. }
  403. function bnpRShiftTo(g, d) {
  404. d.s = this.s;
  405. var e = Math.floor(g / this.DB);
  406. if (e >= this.t) {
  407. d.t = 0;
  408. return
  409. }
  410. var b = g % this.DB;
  411. var a = this.DB - b;
  412. var f = (1 << b) - 1;
  413. d[0] = this[e] >> b;
  414. for (var c = e + 1; c < this.t; ++c) {
  415. d[c - e - 1] |= (this[c] & f) << a;
  416. d[c - e] = this[c] >> b
  417. }
  418. if (b > 0) {
  419. d[this.t - e - 1] |= (this.s & f) << a
  420. }
  421. d.t = this.t - e;
  422. d.clamp()
  423. }
  424. function bnpSubTo(d, f) {
  425. var e = 0,
  426. g = 0,
  427. b = Math.min(d.t, this.t);
  428. while (e < b) {
  429. g += this[e] - d[e];
  430. f[e++] = g & this.DM;
  431. g >>= this.DB
  432. }
  433. if (d.t < this.t) {
  434. g -= d.s;
  435. while (e < this.t) {
  436. g += this[e];
  437. f[e++] = g & this.DM;
  438. g >>= this.DB
  439. }
  440. g += this.s
  441. } else {
  442. g += this.s;
  443. while (e < d.t) {
  444. g -= d[e];
  445. f[e++] = g & this.DM;
  446. g >>= this.DB
  447. }
  448. g -= d.s
  449. }
  450. f.s = (g < 0) ? -1 : 0;
  451. if (g < -1) {
  452. f[e++] = this.DV + g
  453. } else {
  454. if (g > 0) {
  455. f[e++] = g
  456. }
  457. }
  458. f.t = e;
  459. f.clamp()
  460. }
  461. function bnpMultiplyTo(c, e) {
  462. var b = this.abs(),
  463. f = c.abs();
  464. var d = b.t;
  465. e.t = d + f.t;
  466. while (--d >= 0) {
  467. e[d] = 0
  468. }
  469. for (d = 0; d < f.t; ++d) {
  470. e[d + b.t] = b.am(0, f[d], e, d, 0, b.t)
  471. }
  472. e.s = 0;
  473. e.clamp();
  474. if (this.s != c.s) {
  475. BigInteger.ZERO.subTo(e, e)
  476. }
  477. }
  478. function bnpSquareTo(d) {
  479. var a = this.abs();
  480. var b = d.t = 2 * a.t;
  481. while (--b >= 0) {
  482. d[b] = 0
  483. }
  484. for (b = 0; b < a.t - 1; ++b) {
  485. var e = a.am(b, a[b], d, 2 * b, 0, 1);
  486. if ((d[b + a.t] += a.am(b + 1, 2 * a[b], d, 2 * b + 1, e, a.t - b - 1)) >= a.DV) {
  487. d[b + a.t] -= a.DV;
  488. d[b + a.t + 1] = 1
  489. }
  490. }
  491. if (d.t > 0) {
  492. d[d.t - 1] += a.am(b, a[b], d, 2 * b, 0, 1)
  493. }
  494. d.s = 0;
  495. d.clamp()
  496. }
  497. function bnpDivRemTo(n, h, g) {
  498. var w = n.abs();
  499. if (w.t <= 0) {
  500. return
  501. }
  502. var k = this.abs();
  503. if (k.t < w.t) {
  504. if (h != null) {
  505. h.fromInt(0)
  506. }
  507. if (g != null) {
  508. this.copyTo(g)
  509. }
  510. return
  511. }
  512. if (g == null) {
  513. g = nbi()
  514. }
  515. var d = nbi(),
  516. a = this.s,
  517. l = n.s;
  518. var v = this.DB - nbits(w[w.t - 1]);
  519. if (v > 0) {
  520. w.lShiftTo(v, d);
  521. k.lShiftTo(v, g)
  522. } else {
  523. w.copyTo(d);
  524. k.copyTo(g)
  525. }
  526. var p = d.t;
  527. var b = d[p - 1];
  528. if (b == 0) {
  529. return
  530. }
  531. var o = b * (1 << this.F1) + ((p > 1) ? d[p - 2] >> this.F2 : 0);
  532. var A = this.FV / o,
  533. z = (1 << this.F1) / o,
  534. x = 1 << this.F2;
  535. var u = g.t,
  536. s = u - p,
  537. f = (h == null) ? nbi() : h;
  538. d.dlShiftTo(s, f);
  539. if (g.compareTo(f) >= 0) {
  540. g[g.t++] = 1;
  541. g.subTo(f, g)
  542. }
  543. BigInteger.ONE.dlShiftTo(p, f);
  544. f.subTo(d, d);
  545. while (d.t < p) {
  546. d[d.t++] = 0
  547. }
  548. while (--s >= 0) {
  549. var c = (g[--u] == b) ? this.DM : Math.floor(g[u] * A + (g[u - 1] + x) * z);
  550. if ((g[u] += d.am(0, c, g, s, 0, p)) < c) {
  551. d.dlShiftTo(s, f);
  552. g.subTo(f, g);
  553. while (g[u] < --c) {
  554. g.subTo(f, g)
  555. }
  556. }
  557. }
  558. if (h != null) {
  559. g.drShiftTo(p, h);
  560. if (a != l) {
  561. BigInteger.ZERO.subTo(h, h)
  562. }
  563. }
  564. g.t = p;
  565. g.clamp();
  566. if (v > 0) {
  567. g.rShiftTo(v, g)
  568. }
  569. if (a < 0) {
  570. BigInteger.ZERO.subTo(g, g)
  571. }
  572. }
  573. function bnMod(b) {
  574. var c = nbi();
  575. this.abs().divRemTo(b, null, c);
  576. if (this.s < 0 && c.compareTo(BigInteger.ZERO) > 0) {
  577. b.subTo(c, c)
  578. }
  579. return c
  580. }
  581. function Classic(a) {
  582. this.m = a
  583. }
  584. function cConvert(a) {
  585. if (a.s < 0 || a.compareTo(this.m) >= 0) {
  586. return a.mod(this.m)
  587. } else {
  588. return a
  589. }
  590. }
  591. function cRevert(a) {
  592. return a
  593. }
  594. function cReduce(a) {
  595. a.divRemTo(this.m, null, a)
  596. }
  597. function cMulTo(a, c, b) {
  598. a.multiplyTo(c, b);
  599. this.reduce(b)
  600. }
  601. function cSqrTo(a, b) {
  602. a.squareTo(b);
  603. this.reduce(b)
  604. }
  605. Classic.prototype.convert = cConvert;
  606. Classic.prototype.revert = cRevert;
  607. Classic.prototype.reduce = cReduce;
  608. Classic.prototype.mulTo = cMulTo;
  609. Classic.prototype.sqrTo = cSqrTo;
  610. function bnpInvDigit() {
  611. if (this.t < 1) {
  612. return 0
  613. }
  614. var a = this[0];
  615. if ((a & 1) == 0) {
  616. return 0
  617. }
  618. var b = a & 3;
  619. b = (b * (2 - (a & 15) * b)) & 15;
  620. b = (b * (2 - (a & 255) * b)) & 255;
  621. b = (b * (2 - (((a & 65535) * b) & 65535))) & 65535;
  622. b = (b * (2 - a * b % this.DV)) % this.DV;
  623. return (b > 0) ? this.DV - b : -b
  624. }
  625. function Montgomery(a) {
  626. this.m = a;
  627. this.mp = a.invDigit();
  628. this.mpl = this.mp & 32767;
  629. this.mph = this.mp >> 15;
  630. this.um = (1 << (a.DB - 15)) - 1;
  631. this.mt2 = 2 * a.t
  632. }
  633. function montConvert(a) {
  634. var b = nbi();
  635. a.abs().dlShiftTo(this.m.t, b);
  636. b.divRemTo(this.m, null, b);
  637. if (a.s < 0 && b.compareTo(BigInteger.ZERO) > 0) {
  638. this.m.subTo(b, b)
  639. }
  640. return b
  641. }
  642. function montRevert(a) {
  643. var b = nbi();
  644. a.copyTo(b);
  645. this.reduce(b);
  646. return b
  647. }
  648. function montReduce(a) {
  649. while (a.t <= this.mt2) {
  650. a[a.t++] = 0
  651. }
  652. for (var c = 0; c < this.m.t; ++c) {
  653. var b = a[c] & 32767;
  654. var d = (b * this.mpl + (((b * this.mph + (a[c] >> 15) * this.mpl) & this.um) << 15)) & a.DM;
  655. b = c + this.m.t;
  656. a[b] += this.m.am(0, d, a, c, 0, this.m.t);
  657. while (a[b] >= a.DV) {
  658. a[b] -= a.DV;
  659. a[++b]++
  660. }
  661. }
  662. a.clamp();
  663. a.drShiftTo(this.m.t, a);
  664. if (a.compareTo(this.m) >= 0) {
  665. a.subTo(this.m, a)
  666. }
  667. }
  668. function montSqrTo(a, b) {
  669. a.squareTo(b);
  670. this.reduce(b)
  671. }
  672. function montMulTo(a, c, b) {
  673. a.multiplyTo(c, b);
  674. this.reduce(b)
  675. }
  676. Montgomery.prototype.convert = montConvert;
  677. Montgomery.prototype.revert = montRevert;
  678. Montgomery.prototype.reduce = montReduce;
  679. Montgomery.prototype.mulTo = montMulTo;
  680. Montgomery.prototype.sqrTo = montSqrTo;
  681. function bnpIsEven() {
  682. return ((this.t > 0) ? (this[0] & 1) : this.s) == 0
  683. }
  684. function bnpExp(h, j) {
  685. if (h > 4294967295 || h < 1) {
  686. return BigInteger.ONE
  687. }
  688. var f = nbi(),
  689. a = nbi(),
  690. d = j.convert(this),
  691. c = nbits(h) - 1;
  692. d.copyTo(f);
  693. while (--c >= 0) {
  694. j.sqrTo(f, a);
  695. if ((h & (1 << c)) > 0) {
  696. j.mulTo(a, d, f)
  697. } else {
  698. var b = f;
  699. f = a;
  700. a = b
  701. }
  702. }
  703. return j.revert(f)
  704. }
  705. function bnModPowInt(b, a) {
  706. var c;
  707. if (b < 256 || a.isEven()) {
  708. c = new Classic(a)
  709. } else {
  710. c = new Montgomery(a)
  711. }
  712. return this.exp(b, c)
  713. }
  714. //-----摘自网络-----start
  715. BigInteger.prototype.toRadix = bnpToRadix;
  716. BigInteger.prototype.signum = bnSigNum;
  717. BigInteger.prototype.chunkSize = bnpChunkSize;
  718. BigInteger.prototype.intValue = bnIntValue;
  719. //-----摘自网络-----end
  720. BigInteger.prototype.copyTo = bnpCopyTo;
  721. BigInteger.prototype.fromInt = bnpFromInt;
  722. BigInteger.prototype.fromString = bnpFromString;
  723. BigInteger.prototype.clamp = bnpClamp;
  724. BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
  725. BigInteger.prototype.drShiftTo = bnpDRShiftTo;
  726. BigInteger.prototype.lShiftTo = bnpLShiftTo;
  727. BigInteger.prototype.rShiftTo = bnpRShiftTo;
  728. BigInteger.prototype.subTo = bnpSubTo;
  729. BigInteger.prototype.multiplyTo = bnpMultiplyTo;
  730. BigInteger.prototype.squareTo = bnpSquareTo;
  731. BigInteger.prototype.divRemTo = bnpDivRemTo;
  732. BigInteger.prototype.invDigit = bnpInvDigit;
  733. BigInteger.prototype.isEven = bnpIsEven;
  734. BigInteger.prototype.exp = bnpExp;
  735. BigInteger.prototype.toString = bnToString;
  736. BigInteger.prototype.negate = bnNegate;
  737. BigInteger.prototype.abs = bnAbs;
  738. BigInteger.prototype.compareTo = bnCompareTo;
  739. BigInteger.prototype.bitLength = bnBitLength;
  740. BigInteger.prototype.mod = bnMod;
  741. BigInteger.prototype.modPowInt = bnModPowInt;
  742. BigInteger.ZERO = nbv(0);
  743. BigInteger.ONE = nbv(1);
  744. function Arcfour() {
  745. this.i = 0;
  746. this.j = 0;
  747. this.S = new Array()
  748. }
  749. function ARC4init(d) {
  750. var c,
  751. a,
  752. b;
  753. for (c = 0; c < 256; ++c) {
  754. this.S[c] = c
  755. }
  756. a = 0;
  757. for (c = 0; c < 256; ++c) {
  758. a = (a + this.S[c] + d[c % d.length]) & 255;
  759. b = this.S[c];
  760. this.S[c] = this.S[a];
  761. this.S[a] = b
  762. }
  763. this.i = 0;
  764. this.j = 0
  765. }
  766. function ARC4next() {
  767. var a;
  768. this.i = (this.i + 1) & 255;
  769. this.j = (this.j + this.S[this.i]) & 255;
  770. a = this.S[this.i];
  771. this.S[this.i] = this.S[this.j];
  772. this.S[this.j] = a;
  773. return this.S[(a + this.S[this.i]) & 255]
  774. }
  775. Arcfour.prototype.init = ARC4init;
  776. Arcfour.prototype.next = ARC4next;
  777. function prng_newstate() {
  778. return new Arcfour()
  779. }
  780. var rng_psize = 256;
  781. var rng_state;
  782. var rng_pool;
  783. var rng_pptr;
  784. function rng_seed_int(a) {
  785. rng_pool[rng_pptr++] ^= a & 255;
  786. rng_pool[rng_pptr++] ^= (a >> 8) & 255;
  787. rng_pool[rng_pptr++] ^= (a >> 16) & 255;
  788. rng_pool[rng_pptr++] ^= (a >> 24) & 255;
  789. if (rng_pptr >= rng_psize) {
  790. rng_pptr -= rng_psize
  791. }
  792. }
  793. function rng_seed_time() {
  794. rng_seed_int(new Date().getTime())
  795. }
  796. if (rng_pool == null) { //注释
  797. rng_pool = new Array();
  798. rng_pptr = 0;
  799. var t;
  800. // if (navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
  801. // var z = window.crypto.random(32);
  802. // for (t = 0; t < z.length; ++t) {
  803. // rng_pool[rng_pptr++] = z.charCodeAt(t) & 255
  804. // }
  805. // }
  806. // while (rng_pptr < rng_psize) {
  807. // t = Math.floor(65536 * Math.random());
  808. // rng_pool[rng_pptr++] = t >>> 8;
  809. // rng_pool[rng_pptr++] = t & 255
  810. // }
  811. // rng_pptr = 0;
  812. // rng_seed_time()
  813. }
  814. function rng_get_byte() {
  815. if (rng_state == null) {
  816. rng_seed_time();
  817. rng_state = prng_newstate();
  818. rng_state.init(rng_pool);
  819. for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) {
  820. rng_pool[rng_pptr] = 0
  821. }
  822. rng_pptr = 0
  823. }
  824. return rng_state.next()
  825. }
  826. function rng_get_bytes(b) {
  827. var a;
  828. for (a = 0; a < b.length; ++a) {
  829. b[a] = rng_get_byte()
  830. }
  831. }
  832. function SecureRandom() {}
  833. SecureRandom.prototype.nextBytes = rng_get_bytes;
  834. function parseBigInt(b, a) {
  835. return new BigInteger(b, a)
  836. }
  837. function linebrk(c, d) {
  838. var a = "";
  839. var b = 0;
  840. while (b + d < c.length) {
  841. a += c.substring(b, b + d) + "\n";
  842. b += d
  843. }
  844. return a + c.substring(b, c.length)
  845. }
  846. function byte2Hex(a) {
  847. if (a < 16) {
  848. return "0" + a.toString(16)
  849. } else {
  850. return a.toString(16)
  851. }
  852. }
  853. function pkcs1pad2(e, h) {
  854. if (h < e.length + 11) {
  855. // alert("Message too long for RSA");
  856. return null
  857. }
  858. var g = new Array();
  859. var d = e.length - 1;
  860. while (d >= 0 && h > 0) {
  861. var f = e.charCodeAt(d--);
  862. if (f < 128) {
  863. g[--h] = f
  864. } else {
  865. if ((f > 127) && (f < 2048)) {
  866. g[--h] = (f & 63) | 128;
  867. g[--h] = (f >> 6) | 192
  868. } else {
  869. g[--h] = (f & 63) | 128;
  870. g[--h] = ((f >> 6) & 63) | 128;
  871. g[--h] = (f >> 12) | 224
  872. }
  873. }
  874. }
  875. g[--h] = 0;
  876. var b = new SecureRandom();
  877. var a = new Array();
  878. while (h > 2) {
  879. a[0] = 0;
  880. while (a[0] == 0) {
  881. b.nextBytes(a)
  882. }
  883. g[--h] = a[0]
  884. }
  885. g[--h] = 2;
  886. g[--h] = 0;
  887. return new BigInteger(g)
  888. }
  889. function RSAKey() {
  890. this.n = null;
  891. this.e = 0;
  892. this.d = null;
  893. this.p = null;
  894. this.q = null;
  895. this.dmp1 = null;
  896. this.dmq1 = null;
  897. this.coeff = null
  898. }
  899. function RSASetPublic(b, a) {
  900. if (b != null && a != null && b.length > 0 && a.length > 0) {
  901. this.n = parseBigInt(b, 16);
  902. this.e = parseInt(a, 16);
  903. return this.n.toString();
  904. } else {
  905. // alert("Invalid RSA public key")
  906. return 0;
  907. }
  908. }
  909. function RSADoPublic(a) {
  910. return a.modPowInt(this.e, this.n)
  911. }
  912. function RSAEncrypt(d) {
  913. var a = pkcs1pad2(d, (this.n.bitLength() + 7) >> 3);
  914. if (a == null) {
  915. return null
  916. }
  917. var e = this.doPublic(a);
  918. if (e == null) {
  919. return null
  920. }
  921. var b = e.toString(16);
  922. if ((b.length & 1) == 0) {
  923. return b
  924. } else {
  925. return "0" + b
  926. }
  927. return a;
  928. }
  929. RSAKey.prototype.doPublic = RSADoPublic;
  930. RSAKey.prototype.setPublic = RSASetPublic;
  931. RSAKey.prototype.encrypt = RSAEncrypt;
  932. var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  933. var b64pad = "=";
  934. function hex2b64(d) {
  935. var b;
  936. var e;
  937. var a = "";
  938. for (b = 0; b + 3 <= d.length; b += 3) {
  939. e = parseInt(d.substring(b, b + 3), 16);
  940. a += b64map.charAt(e >> 6) + b64map.charAt(e & 63)
  941. }
  942. if (b + 1 == d.length) {
  943. e = parseInt(d.substring(b, b + 1), 16);
  944. a += b64map.charAt(e << 2)
  945. } else {
  946. if (b + 2 == d.length) {
  947. e = parseInt(d.substring(b, b + 2), 16);
  948. a += b64map.charAt(e >> 2) + b64map.charAt((e & 3) << 4)
  949. }
  950. }
  951. while ((a.length & 3) > 0) {
  952. a += b64pad
  953. }
  954. return a
  955. }
  956. function b64tohex(e) {
  957. var c = "";
  958. var d;
  959. var a = 0;
  960. var b;
  961. for (d = 0; d < e.length; ++d) {
  962. if (e.charAt(d) == b64pad) {
  963. break
  964. }
  965. v = b64map.indexOf(e.charAt(d));
  966. if (v < 0) {
  967. continue
  968. }
  969. if (a == 0) {
  970. c += int2char(v >> 2);
  971. b = v & 3;
  972. a = 1
  973. } else {
  974. if (a == 1) {
  975. c += int2char((b << 2) | (v >> 4));
  976. b = v & 15;
  977. a = 2
  978. } else {
  979. if (a == 2) {
  980. c += int2char(b);
  981. c += int2char(v >> 2);
  982. b = v & 3;
  983. a = 3
  984. } else {
  985. c += int2char((b << 2) | (v >> 4));
  986. c += int2char(v & 15);
  987. a = 0
  988. }
  989. }
  990. }
  991. }
  992. if (a == 1) {
  993. c += int2char(b << 2)
  994. }
  995. return c
  996. }
  997. function b64toBA(e) {
  998. var d = b64tohex(e);
  999. var c;
  1000. var b = new Array();
  1001. for (c = 0; 2 * c < d.length; ++c) {
  1002. b[c] = parseInt(d.substring(2 * c, 2 * c + 2), 16)
  1003. }
  1004. return b
  1005. };

感谢原作者https://www.cnblogs.com/xpp142857/p/6994763.html

Jmeter_前端RSA加密下的登陆模拟_引用js文件实现(转)的更多相关文章

  1. Jmeter_前端RSA加密下的登陆模拟_引用js文件实现

    版权声明:本文为博主原创文章,未经博主允许不得转载. 在一次项目实战中,前端登录使用了RSA加密,使用LoadRunner压测的第一步,就是模拟用户登录,可惜loadRunner11并不能录制前端的加 ...

  2. 360浏览器兼容模式下jsp页面访问不到js文件

    360浏览器兼容模式下jsp页面访问不到js文件 查看自己js中的语法问题,不要用ES6的语法,编译不了故找不到js文件 const var of 码出高效 java 比较 所有整型包装类对象之间值的 ...

  3. 个人博客制作如何选择前端模板 thinkcmf后台加载新模板 CSS js文件

    我们的博客后台已经搭建好了,接下来我就要选择一个合适的模板做自己的博客,首先要定位你的博客是做什么用的,是属于什么行业,根据自己博客的定位选择适合的模板. 如果你是设计师,又会前端设计开发,那就可以自 ...

  4. Python3 实现 JS 中 RSA 加密的 NoPadding 模式

    前因后果之哗啦啦废话连篇: 这几天本人在 Python 做某网站登陆的时候,发现其登陆时用户名和密码被加密了 F12 仔细看了一下,发现是调用了一个 js 的 rsa 加密库,页面 dom 中有 rs ...

  5. 【Python3爬虫】破解时光网登录加密参数并实现模拟登录

    一.站点分析 MTime 时光网是一个电影媒体与电商服务平台,而这次做的模拟登录则是依靠其手机端站点,站点地址为:https://m.mtime.cn/#.切换到登录页面,再分别输入账号和错误的密码, ...

  6. springmvc web-info目录下无法引入的js文件无效

    今天在联系spring的时候而然遇到了个不起眼的问题.那就是在html或者说jsp页面中引用js文件的时候总是提示找不到路径.eclipse更是抛出 No mapping to aa.js. 我就奇怪 ...

  7. RSA加密前端JS加密,后端asp.net解密,报异常

    RSA加密前端JS加密,后端asp.net解密,报异常 参考引用:http://www.ohdave.com/rsa/的JS加密库 前端JS加密代码: function GetChangeStr() ...

  8. python RSA加密解密及模拟登录cnblog

    1.公开密钥加密 又称非对称加密,需要一对密钥,一个是私人密钥,另一个则是公开密钥.公钥加密的只能私钥解密,用于加密客户上传数据.私钥加密的数据,公钥可以解密,主要用于数字签名.详细介绍可参见维基百科 ...

  9. RSA加密——前端JSEncrypt

    RSA加密--前端JSEncrypt 介绍 ​ JSEncrypt是一个RSA加密库,在没有SSL加密传输通道支持https协议的情况下,该库可以在http传输重要信息如时,保证数据的安全性.我们小组 ...

随机推荐

  1. Java集合操作类Collections的一些常用方法

    public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); ...

  2. L2-016 愿天下有情人都是失散多年的兄妹(25 分)

    呵呵.大家都知道五服以内不得通婚,即两个人最近的共同祖先如果在五代以内(即本人.父母.祖父母.曾祖父母.高祖父母)则不可通婚.本题就请你帮助一对有情人判断一下,他们究竟是否可以成婚? 输入格式: 输入 ...

  3. jquery--find与children方法的区别

      children方法: find方法: 通过以上的解释,可以总结如下: 1:children及find方法都用是用来获得element的子elements的,两者都不会返回 text node,就 ...

  4. GPIO编程1:用文件IO的方式操作GPIO

    概述 通过 sysfs 方式控制 GPIO,先访问 /sys/class/gpio 目录,向 export 文件写入 GPIO 编号,使得该 GPIO 的操作接口从内核空间暴露到用户空间,GPIO 的 ...

  5. C++类和对象的一个简单的实例

    题目:找出一个整形数组中的元素的最大值 下面,我们用类和对象的方法来做. #include<iostream> using namespace std; class Array_max{ ...

  6. 在64位ubuntu上安装alienbrain客户端

    一.首先从Alienbrain_EN_10.5.zip安装包(网上可搜索下载)里提取出linux版安装文件:Installations/Clients/Linux/NoVM/install.bin并c ...

  7. redis学习总结2

    redis配置文件说明:以下这篇文章已经说明的很明白了.感谢~ http://blog.sina.com.cn/s/blog_636415010101970j.html

  8. idea中,使用Gradle创建的项目,如何变为web项目

    当idea开发项目时,使用gradle构建项目,包引用完后,发现idea并没有正确识别项目为web项目. 主要有两点表现: 1. src/main/resources的resources目录没有或有但 ...

  9. PHP开源系统学习之fluxbb_2

    谴责下某位同学,转载了我的上一篇文章,也不给个原文地址,希望这次再来转时能加上. //检查登录,在common.php判断 //cookie串: 2|dc4fab5bb354be5104bae0aff ...

  10. vs2013提交项目到github

    提交项目之前必须先安装Git,下载地址:https://git-scm.com/download/win 1.登录Github后,在顶部导航栏选择New repository: 2.打开Create ...