JMETER-记一次AES加密登录实例

发表于:2021-1-11 09:52

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:一加一    来源:博客园

#
Jmeter
分享:
  前言
  公司有个网站系统,用户名是明文,密码是加密的,所以搞了好久才登录进去,因此记录下艰辛过程。
  Part 1 了解加密算法
  找研发同事去了解这个是怎样一个加密过程,最后得到的结论是:后端会生成一个16位的随机数,由前端来加密,而前端是用AES的CBC模式加密的。因为前端是用JS实现的,而jmeter是用java,所以不能直接贴前端代码。
  Part 2 开始百度之旅
  各种百度,最后参照2篇博文,然后copy了代码过来优化了下,输出的密码密文如下:
  Part 3 卡住了,不过解决了
  以为这么容易就结束了吗?不,还有第3part呢,在加密算法搞定后,接口一直提示认证失败,起初以为是网上找的加密算法跟公司用的不一样,但是找研发看了,说是一样的,最后终于在研发同事的提醒下,找到原因了,原来是登录的接口请求时要用到前面那个接口生成的cookie,唉,真心不容易。上面只是简单贴了下资料,下面具体说下运用吧。
  Part 4 完整实例演示
  1、添加http请求  获取登录的key接口(GET):http://../login/getSecretKey
  Response Body :{"msg":"success","code":"0","info":{"key":"a2c893cfa0684897"}}
  Response headers:
  HTTP/1.1 200 OK
  Server: openresty/1.11.2.5
  Date: Fri, 27 Nov 2020 13:18:12 GMT
  Content-Type: text/plain;charset=UTF-8
  Content-Length: 62
  Connection: keep-alive
  Set-Cookie: PHPSESSID=a4b06bc0-9974-4b22-aa25-efcd4e969d4e; Path=/; HttpOnly; SameSite=lax
  X-Application-Context: FspService:test:8001
  Access-Control-Allow-Origin: *
  Access-Control-Allow-Methods: GET, POST, OPTIONS
  Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
  正则表达式提取:
  key--从Response Body提取-------------在登录接口会引用到
  PHPSESSID--从Response headers提取---------------在信息头管理器会引用到
  2、添加BeanShell 取样器  对前面接口提取的key进行AES加密,完整代码如下:
  //导入需要的加密包
  import org.apache.commons.codec.binary.Base64;
  import javax.crypto.Cipher;
  import javax.crypto.spec.IvParameterSpec;
  import javax.crypto.spec.SecretKeySpec;
   
      //加密
      public static String encrypt(String data, String key) {
          String ivString = key;
          //偏移量
          byte[] iv = ivString.getBytes();
          try {
              Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
              int blockSize = cipher.getBlockSize();
              byte[] dataBytes = data.getBytes();
              int length = dataBytes.length;
              //计算需填充长度
              if (length % blockSize != 0) {
                  length = length + (blockSize - (length % blockSize));
              }
              byte[] plaintext = new byte[length];
              //填充
              System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
              SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
              //设置偏移量参数
              IvParameterSpec ivSpec = new IvParameterSpec(iv);
              cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
              byte[] encryped = cipher.doFinal(plaintext);
   
              return Base64.encodeBase64String(encryped);
   
          } catch (Exception e) {
              e.printStackTrace();
              return null;
          }
      }
   
      //解密
      public static String desEncrypt(String data, String key) {
   
          String ivString = key;
          byte[] iv = ivString.getBytes();
   
          try {
              byte[] encryp = Base64.decodeBase64(data);
              Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
              SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
              IvParameterSpec ivSpec = new IvParameterSpec(iv);
              cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
              byte[] original = cipher.doFinal(encryp);
              return new String(original);
          } catch (Exception e) {
              e.printStackTrace();
          }
          return null;
      }
      String data = "abcd1234";//这是明文密码
          String key = "${key}";//key引用了变量,即前面接口提取出来的key
          String encrypt = encrypt(data,key);
          String desencrypt = desEncrypt(encrypt, key);
          vars.put("enString",encrypt);//把加密的密码设置为变量enString,供后面登录接口使用
          System.out.println("加密后:"+encrypt);
          System.out.println("解密后:"+desencrypt);
          log.info("加密后:"+encrypt);//打印日志到控制台
          log.info("解密后:"+desencrypt);
  3、添加http请求  登录接口(POST):http://../login/login
  消息体数据:{"password":"${enString}","userName":"用户名","isMobile":false}
  4、HTTP信息头管理器
  Cookie引用第1个接口生成的PHPSESSID值变量,前面就是被这个变量阻塞了好久。
  5、以上就完结啦,下面展示下线程组框架和debug
   
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理    
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号