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. 如果可以,最好找開發用一個實際的接口進行詳細的示例,只看文檔會跑偏。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM