zoukankan      html  css  js  c++  java
  • Jmeter-记一次AES加密登录实例

    前言

      公司有个网站系统,用户名是明文,密码是加密的,所以搞了好久才登录进去,因此记录下艰辛过程。

    Part 1   了解加密算法

      找研发同事去了解这个是怎样一个加密过程,最后得到的结论是:后端会生成一个16位的随机数,由前端来加密,而前端是用AES的CBC模式加密的。因为前端是用JS实现的,而jmeter是用java,所以不能直接贴前端代码。

    Part 2   开始百度之旅

      各种百度,最后参照2篇博文,然后copy了代码过来优化了下,输出的密码密文如下:

    参照的博客地址:

    1.https://www.cnblogs.com/artoftest/p/7277996.html

    2.https://blog.csdn.net/qq_39820860/article/details/95963968

    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

     

  • 相关阅读:
    Sitecore安全:访问权限
    Sitecore 8.2 防火墙规则的权威指南
    Sitecore 8.2 安全性第2部分:安全性编辑器和Access Viewer
    Sitecore安全性第1部分:自定义角色和权限
    Sitecore 8.2 Admin用户帐户解锁
    Sitecore 8.2 数据库权限设置
    cesium 结合 geoserver 实现地图属性查询(附源码下载)
    Vue&Cesium&Ribbon界面: 将桌面GIS搬进浏览器
    leaflet图斑历史时空播放(附源码下载)
    openlayers6结合geoserver实现地图属性查询(附源码下载)
  • 原文地址:https://www.cnblogs.com/Chilam007/p/14050450.html
Copyright © 2011-2022 走看看