版权声明:本文为博主原创文章,未经博主允许不得转载。


  在一次项目实战中,前端登录使用了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脚本

load("sec.min.js");

var modulus = vars.get("modulus");
log.info(modulus);
var exponent = vars.get("exponent");
log.info(exponent); function RSA(){
var rsaKey = new RSAKey();
rsaKey.setPublic(b64tohex("${modulus}"),b64tohex("${exponent}"));
var Enpassword = hex2b64(rsaKey.encrypt("${password}"));
return Enpassword
}
var data = RSA();
log.info(data);
//base64在url中的传输,要注意+ /两个符号
//data = data.replace(/\+/g,"%2B");
//data = data.replace(/\//g,"%2F");
vars.put("Password",data);

  附2----------sec.min.js修改后的js文件

var dbits;
var canary = 244837814094590;
var j_lm = ((canary & 16777215) == 15715070);
function BigInteger(e, d, f) {
 if (e != null) {
  if ("number" == typeof e) {
   this.fromNumber(e, d, f)
  } else {
   if (d == null && "string" != typeof e) {
    this.fromString(e, 256)
   } else {
    this.fromString(e, d)
   }
  }
 }
}
function nbi() {
 return new BigInteger(null)
}
function am1(f, a, b, e, h, g) {
 while (--g >= 0) {
  var d = a * this[f++] + b[e] + h;
  h = Math.floor(d / 67108864);
  b[e++] = d & 67108863
 }
 return h
}
function am2(f, q, r, e, o, a) {
 var k = q & 32767,
 p = q >> 15;
 while (--a >= 0) {
  var d = this[f] & 32767;
  var g = this[f++] >> 15;
  var b = p * d + g * k;
  d = k * d + ((b & 32767) << 15) + r[e] + (o & 1073741823);
  o = (d >>> 30) + (b >>> 15) + p * g + (o >>> 30);
  r[e++] = d & 1073741823
 }
 return o
}
function am3(f, q, r, e, o, a) {
 var k = q & 16383,
 p = q >> 14;
 while (--a >= 0) {
  var d = this[f] & 16383;
  var g = this[f++] >> 14;
  var b = p * d + g * k;
  d = k * d + ((b & 16383) << 14) + r[e] + o;
  o = (d >> 28) + (b >> 14) + p * g;
  r[e++] = d & 268435455
 }
 return o
}
//if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) { //xpp注释
// BigInteger.prototype.am = am2;
// dbits = 30
//} else {
// if (j_lm && (navigator.appName != "Netscape")) {
// BigInteger.prototype.am = am1;
// dbits = 26
// } else {
  BigInteger.prototype.am = am3;
  dbits = 28
// }
//}
BigInteger.prototype.DB = dbits;
BigInteger.prototype.DM = ((1 << dbits) - 1);
BigInteger.prototype.DV = (1 << dbits);
var BI_FP = 52;
BigInteger.prototype.FV = Math.pow(2, BI_FP);
BigInteger.prototype.F1 = BI_FP - dbits;
BigInteger.prototype.F2 = 2 * dbits - BI_FP;
var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
var BI_RC = new Array();
var rr, vv;
rr = "0".charCodeAt(0);
for (vv = 0; vv <= 9; ++vv) {
 BI_RC[rr++] = vv
}
rr = "a".charCodeAt(0);
for (vv = 10; vv < 36; ++vv) {
 BI_RC[rr++] = vv
}
rr = "A".charCodeAt(0);
for (vv = 10; vv < 36; ++vv) {
 BI_RC[rr++] = vv
}
function int2char(a) {
 return BI_RM.charAt(a)
}
function intAt(b, a) {
 var d = BI_RC[b.charCodeAt(a)];
 return (d == null) ? -1 : d
}
//-----摘自网络-----start
function bnpToRadix(b) {
    if (b == null) {
        b = 10
    }
    if (this.signum() == 0 || b < 2 || b > 36) {
        return "0"
    }
    var cs = this.chunkSize(b);
    var a = Math.pow(b, cs);
    var d = nbv(a),
        y = nbi(),
        z = nbi(),
        r = "";
    this.divRemTo(d, y, z);
    while (y.signum() > 0) {
        r = (a + z.intValue()).toString(b).substr(1) + r;
        y.divRemTo(d, y, z)
    }
    return z.intValue().toString(b) + r
}
function bnSigNum() {
    if (this.s < 0) {
        return -1
    } else {
        if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) {
            return 0
        } else {
            return 1
        }
    }
}
function bnpChunkSize(r) {
    return Math.floor(Math.LN2 * this.DB / Math.log(r))
}
function bnIntValue() {
    if (this.s < 0) {
        if (this.t == 1) {
            return this[0] - this.DV
        } else {
            if (this.t == 0) {
                return -1
            }
        }
    } else {
        if (this.t == 1) {
            return this[0]
        } else {
            if (this.t == 0) {
                return 0
            }
        }
    }
    return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]
}
//-----摘自网络-----end function bnpCopyTo(b) {
 for (var a = this.t - 1; a >= 0; --a) {
  b[a] = this[a]
 }
 b.t = this.t;
 b.s = this.s
}
function bnpFromInt(a) {
 this.t = 1;
 this.s = (a < 0) ? -1 : 0;
 if (a > 0) {
  this[0] = a
 } else {
  if (a < -1) {
   this[0] = a + DV
  } else {
   this.t = 0
  }
 }
}
function nbv(a) {
 var b = nbi();
 b.fromInt(a);
 return b
}
function bnpFromString(h, c) {
 var e;
 if (c == 16) {
  e = 4
 } else {
  if (c == 8) {
   e = 3
  } else {
   if (c == 256) {
    e = 8
   } else {
    if (c == 2) {
     e = 1
    } else {
     if (c == 32) {
      e = 5
     } else {
      if (c == 4) {
       e = 2
      } else {
       this.fromRadix(h, c);
       return
      }
     }
    }
   }
  }
 }
 this.t = 0;
 this.s = 0;
 var g = h.length,
 d = false,
 f = 0;
 while (--g >= 0) {
  var a = (e == 8) ? h[g] & 255 : intAt(h, g);
  if (a < 0) {
   if (h.charAt(g) == "-") {
    d = true
   }
   continue
  }
  d = false;
  if (f == 0) {
   this[this.t++] = a
  } else {
   if (f + e > this.DB) {
    this[this.t - 1] |= (a & ((1 << (this.DB - f)) - 1)) << f;
    this[this.t++] = (a >> (this.DB - f))
   } else {
    this[this.t - 1] |= a << f
   }
  }
  f += e;
  if (f >= this.DB) {
   f -= this.DB
  }
 }
 if (e == 8 && (h[0] & 128) != 0) {
  this.s = -1;
  if (f > 0) {
   this[this.t - 1] |= ((1 << (this.DB - f)) - 1) << f
  }
 }
 this.clamp();
 if (d) {
  BigInteger.ZERO.subTo(this, this)
 }
}
function bnpClamp() {
 var a = this.s & this.DM;
 while (this.t > 0 && this[this.t - 1] == a) {
  --this.t
 }
}
function bnToString(c) {
 if (this.s < 0) {
  return "-" + this.negate().toString(c)
 }
 var e;
 if (c == 16) {
  e = 4
 } else {
  if (c == 8) {
   e = 3
  } else {
   if (c == 2) {
    e = 1
   } else {
    if (c == 32) {
     e = 5
    } else {
     if (c == 4) {
      e = 2
     } else {
      return this.toRadix(c)
     }
    }
   }
  }
 }
 var g = (1 << e) - 1,
 l,
 a = false,
 h = "",
 f = this.t;
 var j = this.DB - (f * this.DB) % e;
 if (f-- > 0) {
  if (j < this.DB && (l = this[f] >> j) > 0) {
   a = true;
   h = int2char(l)
  }
  while (f >= 0) {
   if (j < e) {
    l = (this[f] & ((1 << j) - 1)) << (e - j);
    l |= this[--f] >> (j += this.DB - e)
   } else {
    l = (this[f] >> (j -= e)) & g;
    if (j <= 0) {
     j += this.DB;
     --f
    }
   }
   if (l > 0) {
    a = true
   }
   if (a) {
    h += int2char(l)
   }
  }
 }
 return a ? h : "0"
}
function bnNegate() {
 var a = nbi();
 BigInteger.ZERO.subTo(this, a);
 return a
}
function bnAbs() {
 return (this.s < 0) ? this.negate() : this
}
function bnCompareTo(b) {
 var d = this.s - b.s;
 if (d != 0) {
  return d
 }
 var c = this.t;
 d = c - b.t;
 if (d != 0) {
  return (this.s < 0) ? -d : d
 }
 while (--c >= 0) {
  if ((d = this[c] - b[c]) != 0) {
   return d
  }
 }
 return 0
}
function nbits(a) {
 var c = 1,
 b;
 if ((b = a >>> 16) != 0) {
  a = b;
  c += 16
 }
 if ((b = a >> 8) != 0) {
  a = b;
  c += 8
 }
 if ((b = a >> 4) != 0) {
  a = b;
  c += 4
 }
 if ((b = a >> 2) != 0) {
  a = b;
  c += 2
 }
 if ((b = a >> 1) != 0) {
  a = b;
  c += 1
 }
 return c
}
function bnBitLength() {
 if (this.t <= 0) {
  return 0
 }
 return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM))
} function bnpDLShiftTo(c, b) {
 var a;
 for (a = this.t - 1; a >= 0; --a) {
  b[a + c] = this[a]
 }
 for (a = c - 1; a >= 0; --a) {
  b[a] = 0
 }
 b.t = this.t + c;
 b.s = this.s
}
function bnpDRShiftTo(c, b) {
 for (var a = c; a < this.t; ++a) {
  b[a - c] = this[a]
 }
 b.t = Math.max(this.t - c, 0);
 b.s = this.s
}
function bnpLShiftTo(j, e) {
 var b = j % this.DB;
 var a = this.DB - b;
 var g = (1 << a) - 1;
 var f = Math.floor(j / this.DB),
 h = (this.s << b) & this.DM,
 d;
 for (d = this.t - 1; d >= 0; --d) {
  e[d + f + 1] = (this[d] >> a) | h;
  h = (this[d] & g) << b
 }
 for (d = f - 1; d >= 0; --d) {
  e[d] = 0
 }
 e[f] = h;
 e.t = this.t + f + 1;
 e.s = this.s;
 e.clamp()
}
function bnpRShiftTo(g, d) {
 d.s = this.s;
 var e = Math.floor(g / this.DB);
 if (e >= this.t) {
  d.t = 0;
  return
 }
 var b = g % this.DB;
 var a = this.DB - b;
 var f = (1 << b) - 1;
 d[0] = this[e] >> b;
 for (var c = e + 1; c < this.t; ++c) {
  d[c - e - 1] |= (this[c] & f) << a;
  d[c - e] = this[c] >> b
 }
 if (b > 0) {
  d[this.t - e - 1] |= (this.s & f) << a
 }
 d.t = this.t - e;
 d.clamp()
}
function bnpSubTo(d, f) {
 var e = 0,
 g = 0,
 b = Math.min(d.t, this.t);
 while (e < b) {
  g += this[e] - d[e];
  f[e++] = g & this.DM;
  g >>= this.DB
 }
 if (d.t < this.t) {
  g -= d.s;
  while (e < this.t) {
   g += this[e];
   f[e++] = g & this.DM;
   g >>= this.DB
  }
  g += this.s
 } else {
  g += this.s;
  while (e < d.t) {
   g -= d[e];
   f[e++] = g & this.DM;
   g >>= this.DB
  }
  g -= d.s
 }
 f.s = (g < 0) ? -1 : 0;
 if (g < -1) {
  f[e++] = this.DV + g
 } else {
  if (g > 0) {
   f[e++] = g
  }
 }
 f.t = e;
 f.clamp()
}
function bnpMultiplyTo(c, e) {
 var b = this.abs(),
 f = c.abs();
 var d = b.t;
 e.t = d + f.t;
 while (--d >= 0) {
  e[d] = 0
 }
 for (d = 0; d < f.t; ++d) {
  e[d + b.t] = b.am(0, f[d], e, d, 0, b.t)
 }
 e.s = 0;
 e.clamp();
 if (this.s != c.s) {
  BigInteger.ZERO.subTo(e, e)
 }
}
function bnpSquareTo(d) {
 var a = this.abs();
 var b = d.t = 2 * a.t;
 while (--b >= 0) {
  d[b] = 0
 }
 for (b = 0; b < a.t - 1; ++b) {
  var e = a.am(b, a[b], d, 2 * b, 0, 1);
  if ((d[b + a.t] += a.am(b + 1, 2 * a[b], d, 2 * b + 1, e, a.t - b - 1)) >= a.DV) {
   d[b + a.t] -= a.DV;
   d[b + a.t + 1] = 1
  }
 }
 if (d.t > 0) {
  d[d.t - 1] += a.am(b, a[b], d, 2 * b, 0, 1)
 }
 d.s = 0;
 d.clamp()
}
function bnpDivRemTo(n, h, g) {
 var w = n.abs();
 if (w.t <= 0) {
  return
 }
 var k = this.abs();
 if (k.t < w.t) {
  if (h != null) {
   h.fromInt(0)
  }
  if (g != null) {
   this.copyTo(g)
  }
  return
 }
 if (g == null) {
  g = nbi()
 }
 var d = nbi(),
 a = this.s,
 l = n.s;
 var v = this.DB - nbits(w[w.t - 1]);
 if (v > 0) {
  w.lShiftTo(v, d);
  k.lShiftTo(v, g)
 } else {
  w.copyTo(d);
  k.copyTo(g)
 }
 var p = d.t;
 var b = d[p - 1];
 if (b == 0) {
  return
 }
 var o = b * (1 << this.F1) + ((p > 1) ? d[p - 2] >> this.F2 : 0);
 var A = this.FV / o,
 z = (1 << this.F1) / o,
 x = 1 << this.F2;
 var u = g.t,
 s = u - p,
 f = (h == null) ? nbi() : h;
 d.dlShiftTo(s, f);
 if (g.compareTo(f) >= 0) {
  g[g.t++] = 1;
  g.subTo(f, g)
 }
 BigInteger.ONE.dlShiftTo(p, f);
 f.subTo(d, d);
 while (d.t < p) {
  d[d.t++] = 0
 }
 while (--s >= 0) {
  var c = (g[--u] == b) ? this.DM : Math.floor(g[u] * A + (g[u - 1] + x) * z);
  if ((g[u] += d.am(0, c, g, s, 0, p)) < c) {
   d.dlShiftTo(s, f);
   g.subTo(f, g);
   while (g[u] < --c) {
    g.subTo(f, g)
   }
  }
 }
 if (h != null) {
  g.drShiftTo(p, h);
  if (a != l) {
   BigInteger.ZERO.subTo(h, h)
  }
 }
 g.t = p;
 g.clamp();
 if (v > 0) {
  g.rShiftTo(v, g)
 }
 if (a < 0) {
  BigInteger.ZERO.subTo(g, g)
 }
}
function bnMod(b) {
 var c = nbi();
 this.abs().divRemTo(b, null, c);
 if (this.s < 0 && c.compareTo(BigInteger.ZERO) > 0) {
  b.subTo(c, c)
 }
 return c
}
function Classic(a) {
 this.m = a
}
function cConvert(a) {
 if (a.s < 0 || a.compareTo(this.m) >= 0) {
  return a.mod(this.m)
 } else {
  return a
 }
}
function cRevert(a) {
 return a
}
function cReduce(a) {
 a.divRemTo(this.m, null, a)
}
function cMulTo(a, c, b) {
 a.multiplyTo(c, b);
 this.reduce(b)
}
function cSqrTo(a, b) {
 a.squareTo(b);
 this.reduce(b)
}
Classic.prototype.convert = cConvert;
Classic.prototype.revert = cRevert;
Classic.prototype.reduce = cReduce;
Classic.prototype.mulTo = cMulTo;
Classic.prototype.sqrTo = cSqrTo;
function bnpInvDigit() {
 if (this.t < 1) {
  return 0
 }
 var a = this[0];
 if ((a & 1) == 0) {
  return 0
 }
 var b = a & 3;
 b = (b * (2 - (a & 15) * b)) & 15;
 b = (b * (2 - (a & 255) * b)) & 255;
 b = (b * (2 - (((a & 65535) * b) & 65535))) & 65535;
 b = (b * (2 - a * b % this.DV)) % this.DV;
 return (b > 0) ? this.DV - b : -b
}
function Montgomery(a) {
 this.m = a;
 this.mp = a.invDigit();
 this.mpl = this.mp & 32767;
 this.mph = this.mp >> 15;
 this.um = (1 << (a.DB - 15)) - 1;
 this.mt2 = 2 * a.t
}
function montConvert(a) {
 var b = nbi();
 a.abs().dlShiftTo(this.m.t, b);
 b.divRemTo(this.m, null, b);
 if (a.s < 0 && b.compareTo(BigInteger.ZERO) > 0) {
  this.m.subTo(b, b)
 }
 return b
}
function montRevert(a) {
 var b = nbi();
 a.copyTo(b);
 this.reduce(b);
 return b
}
function montReduce(a) {
 while (a.t <= this.mt2) {
  a[a.t++] = 0
 }
 for (var c = 0; c < this.m.t; ++c) {
  var b = a[c] & 32767;
  var d = (b * this.mpl + (((b * this.mph + (a[c] >> 15) * this.mpl) & this.um) << 15)) & a.DM;
  b = c + this.m.t;
  a[b] += this.m.am(0, d, a, c, 0, this.m.t);
  while (a[b] >= a.DV) {
   a[b] -= a.DV;
   a[++b]++
  }
 }
 a.clamp();
 a.drShiftTo(this.m.t, a);
 if (a.compareTo(this.m) >= 0) {
  a.subTo(this.m, a)
 }
}
function montSqrTo(a, b) {
 a.squareTo(b);
 this.reduce(b)
}
function montMulTo(a, c, b) {
 a.multiplyTo(c, b);
 this.reduce(b)
}
Montgomery.prototype.convert = montConvert;
Montgomery.prototype.revert = montRevert;
Montgomery.prototype.reduce = montReduce;
Montgomery.prototype.mulTo = montMulTo;
Montgomery.prototype.sqrTo = montSqrTo;
function bnpIsEven() {
 return ((this.t > 0) ? (this[0] & 1) : this.s) == 0
}
function bnpExp(h, j) {
 if (h > 4294967295 || h < 1) {
  return BigInteger.ONE
 }
 var f = nbi(),
 a = nbi(),
 d = j.convert(this),
 c = nbits(h) - 1;
 d.copyTo(f);
 while (--c >= 0) {
  j.sqrTo(f, a);
  if ((h & (1 << c)) > 0) {
   j.mulTo(a, d, f)
  } else {
   var b = f;
   f = a;
   a = b
  }
 }
 return j.revert(f)
}
function bnModPowInt(b, a) {
 var c;
 if (b < 256 || a.isEven()) {
  c = new Classic(a)
 } else {
  c = new Montgomery(a)
 }
 return this.exp(b, c)
}
//-----摘自网络-----start
BigInteger.prototype.toRadix = bnpToRadix;
BigInteger.prototype.signum = bnSigNum;
BigInteger.prototype.chunkSize = bnpChunkSize;
BigInteger.prototype.intValue = bnIntValue;
//-----摘自网络-----end
BigInteger.prototype.copyTo = bnpCopyTo;
BigInteger.prototype.fromInt = bnpFromInt;
BigInteger.prototype.fromString = bnpFromString;
BigInteger.prototype.clamp = bnpClamp;
BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
BigInteger.prototype.drShiftTo = bnpDRShiftTo;
BigInteger.prototype.lShiftTo = bnpLShiftTo;
BigInteger.prototype.rShiftTo = bnpRShiftTo;
BigInteger.prototype.subTo = bnpSubTo;
BigInteger.prototype.multiplyTo = bnpMultiplyTo;
BigInteger.prototype.squareTo = bnpSquareTo;
BigInteger.prototype.divRemTo = bnpDivRemTo;
BigInteger.prototype.invDigit = bnpInvDigit;
BigInteger.prototype.isEven = bnpIsEven;
BigInteger.prototype.exp = bnpExp;
BigInteger.prototype.toString = bnToString;
BigInteger.prototype.negate = bnNegate;
BigInteger.prototype.abs = bnAbs;
BigInteger.prototype.compareTo = bnCompareTo;
BigInteger.prototype.bitLength = bnBitLength;
BigInteger.prototype.mod = bnMod;
BigInteger.prototype.modPowInt = bnModPowInt;
BigInteger.ZERO = nbv(0);
BigInteger.ONE = nbv(1);
function Arcfour() {
 this.i = 0;
 this.j = 0;
 this.S = new Array()
}
function ARC4init(d) {
 var c,
 a,
 b;
 for (c = 0; c < 256; ++c) {
  this.S[c] = c
 }
 a = 0;
 for (c = 0; c < 256; ++c) {
  a = (a + this.S[c] + d[c % d.length]) & 255;
  b = this.S[c];
  this.S[c] = this.S[a];
  this.S[a] = b
 }
 this.i = 0;
 this.j = 0
}
function ARC4next() {
 var a;
 this.i = (this.i + 1) & 255;
 this.j = (this.j + this.S[this.i]) & 255;
 a = this.S[this.i];
 this.S[this.i] = this.S[this.j];
 this.S[this.j] = a;
 return this.S[(a + this.S[this.i]) & 255]
}
Arcfour.prototype.init = ARC4init;
Arcfour.prototype.next = ARC4next;
function prng_newstate() {
 return new Arcfour()
}
var rng_psize = 256;
var rng_state;
var rng_pool;
var rng_pptr;
function rng_seed_int(a) {
 rng_pool[rng_pptr++] ^= a & 255;
 rng_pool[rng_pptr++] ^= (a >> 8) & 255;
 rng_pool[rng_pptr++] ^= (a >> 16) & 255;
 rng_pool[rng_pptr++] ^= (a >> 24) & 255;
 if (rng_pptr >= rng_psize) {
  rng_pptr -= rng_psize
 }
}
function rng_seed_time() {
 rng_seed_int(new Date().getTime())
}
 if (rng_pool == null) { //注释
  rng_pool = new Array();
  rng_pptr = 0;
  var t;
 // if (navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
 // var z = window.crypto.random(32);
 // for (t = 0; t < z.length; ++t) {
 // rng_pool[rng_pptr++] = z.charCodeAt(t) & 255
 // }
 // }
 // while (rng_pptr < rng_psize) {
 // t = Math.floor(65536 * Math.random());
 // rng_pool[rng_pptr++] = t >>> 8;
 // rng_pool[rng_pptr++] = t & 255
 // }
 // rng_pptr = 0;
 // rng_seed_time()
 }
function rng_get_byte() {
 if (rng_state == null) {
  rng_seed_time();
  rng_state = prng_newstate();
  rng_state.init(rng_pool);
  for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) {
   rng_pool[rng_pptr] = 0
  }
  rng_pptr = 0
 }
 return rng_state.next()
}
function rng_get_bytes(b) {
 var a;
 for (a = 0; a < b.length; ++a) {
  b[a] = rng_get_byte()
 }
}
function SecureRandom() {}
SecureRandom.prototype.nextBytes = rng_get_bytes;
function parseBigInt(b, a) {
 return new BigInteger(b, a)
}
function linebrk(c, d) {
 var a = "";
 var b = 0;
 while (b + d < c.length) {
  a += c.substring(b, b + d) + "\n";
  b += d
 }
 return a + c.substring(b, c.length)
}
function byte2Hex(a) {
 if (a < 16) {
  return "0" + a.toString(16)
 } else {
  return a.toString(16)
 }
}
function pkcs1pad2(e, h) {
 if (h < e.length + 11) {
// alert("Message too long for RSA");
  return null
 }
 var g = new Array();
 var d = e.length - 1;
 while (d >= 0 && h > 0) {
  var f = e.charCodeAt(d--);
  if (f < 128) {
   g[--h] = f
  } else {
   if ((f > 127) && (f < 2048)) {
    g[--h] = (f & 63) | 128;
    g[--h] = (f >> 6) | 192
   } else {
    g[--h] = (f & 63) | 128;
    g[--h] = ((f >> 6) & 63) | 128;
    g[--h] = (f >> 12) | 224
   }
  }
 }
 g[--h] = 0;
 var b = new SecureRandom();
 var a = new Array();
 while (h > 2) {
  a[0] = 0;
  while (a[0] == 0) {
   b.nextBytes(a)
  }
  g[--h] = a[0]
 }
 g[--h] = 2;
 g[--h] = 0;
 return new BigInteger(g)
}
function RSAKey() {
 this.n = null;
 this.e = 0;
 this.d = null;
 this.p = null;
 this.q = null;
 this.dmp1 = null;
 this.dmq1 = null;
 this.coeff = null
}
function RSASetPublic(b, a) {
 if (b != null && a != null && b.length > 0 && a.length > 0) {
  this.n = parseBigInt(b, 16);
  this.e = parseInt(a, 16);
  return this.n.toString();
 } else {
// alert("Invalid RSA public key")
  return 0;
 }
}
function RSADoPublic(a) {
 return a.modPowInt(this.e, this.n)
}
function RSAEncrypt(d) {
 var a = pkcs1pad2(d, (this.n.bitLength() + 7) >> 3);
 if (a == null) {
  return null
 }
 var e = this.doPublic(a);
 if (e == null) {
  return null
 }
 var b = e.toString(16);
 if ((b.length & 1) == 0) {
  return b
 } else {
  return "0" + b
 }
 return a;
}
RSAKey.prototype.doPublic = RSADoPublic;
RSAKey.prototype.setPublic = RSASetPublic;
RSAKey.prototype.encrypt = RSAEncrypt;
var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var b64pad = "=";
function hex2b64(d) {
 var b;
 var e;
 var a = "";
 for (b = 0; b + 3 <= d.length; b += 3) {
  e = parseInt(d.substring(b, b + 3), 16);
  a += b64map.charAt(e >> 6) + b64map.charAt(e & 63)
 }
 if (b + 1 == d.length) {
  e = parseInt(d.substring(b, b + 1), 16);
  a += b64map.charAt(e << 2)
 } else {
  if (b + 2 == d.length) {
   e = parseInt(d.substring(b, b + 2), 16);
   a += b64map.charAt(e >> 2) + b64map.charAt((e & 3) << 4)
  }
 }
 while ((a.length & 3) > 0) {
  a += b64pad
 }
 return a
}
function b64tohex(e) {
 var c = "";
 var d;
 var a = 0;
 var b;
 for (d = 0; d < e.length; ++d) {
  if (e.charAt(d) == b64pad) {
   break
  }
  v = b64map.indexOf(e.charAt(d));
  if (v < 0) {
   continue
  }
  if (a == 0) {
   c += int2char(v >> 2);
   b = v & 3;
   a = 1
  } else {
   if (a == 1) {
    c += int2char((b << 2) | (v >> 4));
    b = v & 15;
    a = 2
   } else {
    if (a == 2) {
     c += int2char(b);
     c += int2char(v >> 2);
     b = v & 3;
     a = 3
    } else {
     c += int2char((b << 2) | (v >> 4));
     c += int2char(v & 15);
     a = 0
    }
   }
  }
 }
 if (a == 1) {
  c += int2char(b << 2)
 }
 return c
}
function b64toBA(e) {
 var d = b64tohex(e);
 var c;
 var b = new Array();
 for (c = 0; 2 * c < d.length; ++c) {
  b[c] = parseInt(d.substring(2 * c, 2 * c + 2), 16)
 }
 return b
};

  

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

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

    在一次项目实战中,前端登录使用了RSA加密,使用LoadRunner压测的第一步,就是模拟用户登录,可惜loadRunner11并不能录制前端的加密过程,并且安装的LR是基于C语言版,网络上关于RSA ...

  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. RNA-Seq数据去接头(Adapter)

    1.adapter是一段短的序列已知的核酸链,用于链接序列未知的目标测序片段. 2.barcode,也称为index,是一段很短的寡居核酸链,用于在多个样品混合测序时,标记不同的样品. 3.inser ...

  2. 2017/2/7utf-8与GBK的区别与修改

    1.GBK:是中文字符编码 2.UTF-8:是国际编码 3.使用GBK与UTF-8编码更耗内存,同时有英文字符多的 尽量用UTF-8编码 4.在项目中,几个修改字符串的方法:

  3. OneZero第三周第三次站立会议(2016.4.6)

    1. 时间: 13:05--13:15  共计10分钟. 2. 成员: X 夏一鸣 * 组长 (博客:http://www.cnblogs.com/xiaym896/), G 郭又铭 (博客:http ...

  4. usart下位机输出使用printf的格式化技巧

    输出使用printf("0x%3X ", I2c_Buf_Write[i]);时,上位机接收过程,使用文本格式,显示结果如下 虽然是保留了三位的宽度,但是并不美观. 相比于使用pr ...

  5. unity在一个对象上挂多个一样的脚本怎么获取

    使用GetComponents获取,存到一个该类的数组里

  6. 核心一:IoC

    IoC 1.中文名称:控制反转 2.英文名称:(Inversion of Control) 3.IoC是什么? 3.1 IoC 完成的事情原先由程序员主动通过new 实例化对象事情,转交给Spring ...

  7. 高效能程序员的七个习惯【csdn】

    从网上看到的,感觉挺不错的! Beautiful is better than ugly. Explicit is better than implicit. Simple is better tha ...

  8. IntellJ IDEA 对于 Spring Boot2.0.2 配置文件application.properties 配置

    1.指定文件名称: 打开IDEA编辑位置: 找到如图位置: 点开后方设置 设置输入如下内容:(默认的配置文件名字可以使用--spring.config.name来指定,只需要指定文件的名字,文件扩展名 ...

  9. 词袋模型(BOW, bag of words)

    词集模型:单词构成的集合,每个单词只出现一次. 词袋模型:把每一个单词都进行统计,同时计算每个单词出现的次数. 在train_x中,总共有6篇文档,每一行代表一个样本即一篇文档.我们的目标是将trai ...

  10. ★ prototype、__proto__ 详解

    # var Person = function(name) { this.name = name; } var p = new Person(); //new操作符的操作是 var p = {} p. ...