zoukankan      html  css  js  c++  java
  • Jmeter使用beanshell对数据进行加密传输

    首先,来看一下接口签名加密规则

    1.需要参于签名的参数:
    
    	a. 在请求参数列表中,除去 cliSign 参数外,其他需要使用到的参数皆是要签名的参数。
    	
    2.生成签名字符串
    
    	a.	没有值的参数无需传递,也无需包含到待签名数据中
    	
    	b.	签名数据应该是原生值而不是 encoding 之后的值
    	
    	c.	若遇参数值为数组时,请以char=7对应字符进行分割此参数的多个值
    	
    	d. 按签名参数 a 到 z 的顺序排序("&"是分割开出多个参数)
    	
    		签名参数字符串如下:
    		
    		params = channel =0&password=abc&userid=13876
    		
    		pass = md5(params + appkey).toLowerCase() 注:“+”加与为字符串相连符,不在签名字符里,appkey为秘钥,为双方平台约定字符
    
    		加密后cliSign = pass.substring(5, 21);全部小写后,获取前8到24位共16位传到服务端;
    
    		
    	e.  针对部分CDN接口若有传中文,客户端请在对中文URLEncoder后加密
    	
    3.开发测试环境签名密钥:
    
    	appkey="test888"
    

    beanshell代码如下:

    import org.apache.commons.codec.digest.DigestUtils; 
    
    //业务字段
    String accessToken = vars.get("access_token");
    String userId = vars.get("user_id");
    String videoId = vars.get("videoId");
    
    //POST/get请求公共参数
    String appId = vars.get("appId");
    String brand = vars.get("brand");
    String channel = vars.get("channel");
    String device = vars.get("device");
    String platform = vars.get("platform");
    String sysVersion = vars.get("sysVersion");
    String times = vars.get("times");
    String version = vars.get("version");
    String appkey = vars.get("appkey");
    
    //将签名传给cliSign参数,使用treemap,可自动进行排序
    Map map = new TreeMap();
    
    map.put("accessToken", accessToken);
    map.put("userId", userId);
    map.put("videoId", videoId);
    
    map.put("appId", appId);
    map.put("brand", brand);
    map.put("channel", channel);
    map.put("device", device);
    map.put("platform", platform);
    map.put("sysVersion", sysVersion);
    map.put("times",times);
    map.put("version", version);
    
    //URLEncoder.encode(value, "UTF-8")   对中文进行格式化,这里不需要  
    
    StringBuffer sb = new StringBuffer();
    for (Map.Entry entry : map.entrySet()) {
    	sb.append(entry.getKey() + "=" + entry.getValue());
    	sb.append("&");
    	}
    	String s = sb.toString();
    	if (s.endsWith("&")) {
    		s = org.apache.commons.lang.StringUtils.substringBeforeLast(s, "&");
    	}
    	log.info("Map转换为URL编码"+s);
    
    String str1 = s+appkey;
    log.info("待加密字符串为:"+str1);
    //进行md5加密
    String pass = DigestUtils.md5Hex(str1).toLowerCase();
    log.info("加密后的值:"+pass);
    //截取前8到21位为签名
    String sign = pass.substring(5, 21);
    log.info("最终签名为:"+sign);
    //将签名传给cliSign参数
    vars.put("cliSign",sign);
    
    
    

    技巧总结

    1. 将可能发生变动的参数均进行参数化,然后使用vars.put()方法获取,这样以后就不需要再修改beanshell中的代码
    2. 由于每个接口都需要用一个beanshell来获取签名,最好将业务参数和公共参数分开,便于修改和查看
    3. 对于关键变量,将其打印到日志中,方便定位问题,比如我之前碰到的问题:
        a. 不确定拼接后的参数是否正确、顺序是否正确,是否需要用URLEncoder进行转码或者获取参数时出错等,只有打印出来后才能知道;
        b.不确定加密后的值是否正确,有可能与开发使用的加密方法不一致;
        c. 不确定截取后,最终签名是否正确
        签名机制就是这样,每一步都不能出错,需要步步为营,抽丝剥茧。找到是哪一步出的问题
    

    附录:URL在线转码测试

    本次的坑

    1. 从csv文件中读取的参数,自动加上了“”,导致最终传参不正确(在csv文件配置中将【是否允许带引号】设置为true即可);
    2. 对参数进行了URLEncoder转码,后来发现不需要;
    3. 能复制就不要手写,有的时候参数名就错了一个字母,但是找起来真的很头疼;
    4. 如果可以,最好找开发用一个实际的接口进行详细的示例,只看文档会跑偏。
  • 相关阅读:
    linux命令--cp
    linux命令--mv
    CSS属性值定义语法中的符号说名
    select选项改变时获取选中的option的值
    JS截取字符串:slice(),substring()和substr()
    正则表达式进行密码验证
    利用@media实现IE hack
    javascript版1024游戏源码
    canvas写的一个小时钟demo
    gl.vertexAtteib3f P42 讲数据传给location参数指定的attribute变量
  • 原文地址:https://www.cnblogs.com/51benpao/p/13118078.html
Copyright © 2011-2022 走看看