zoukankan      html  css  js  c++  java
  • Jmeter_前端RSA加密下的登陆模拟_引用js文件实现(转)

    在一次项目实战中,前端登录使用了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);
    View Code
    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) + "
    ";
      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
    };
    View Code

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

  • 相关阅读:
    js对select动态添加和删除OPTION
    文本框textarea实时提示还可以输入多少文字
    JavaScript中统计Textarea字数并提示还能输入的字符
    inupt textarea提示文字(点击消失,不输入恢复)
    inupt textarea提示文字(点击消失,不输入恢复)及限制字数
    Server.MapPath()获取本机绝对路径
    cocos基础教程(12)点击交互的三种处理
    cocos基础教程(9)声音和音效
    cocos进阶教程(2)多分辨率支持策略和原理
    cocos基础教程(10)纹理缓存技术
  • 原文地址:https://www.cnblogs.com/a00ium/p/10361483.html
Copyright © 2011-2022 走看看