接口测试 接口测试中的验签及机密实现

Flange · 2018年06月07日 · 最后由 orangleliu 回复于 2018年06月08日 · 2431 次阅读

接口请求中的签名 signature,是一串加密后的字符串,作为请求体的一个参数放在 Request 中。
对接口中传递的参数进行加密,需要以密文的形式发送出去。
一、JMeter 中 BeanShell PreProcessor 进行编写验签方法,代码如下:

public class SignTest{

public static String getSignature(Map params,String Key) {

Map sortedParams = new TreeMap(params);

//先将这些请求参数以其参数名的字典序升序进行排序

Set entrys = sortedParams.entrySet();

// 遍历排序后的字典,将所有参数按""key=value""格式拼接在一起

StringBuilder basestring = new StringBuilder();

for (Entry param : entrys) {

String key = param.getKey();

String value = param.getValue();

if(value == null){

value = "";

}

basestring.append(key).append("=").append(value);

}

basestring.append(Key);

//log.info("Sign Source:" + basestring);

// 使用 MD5 对待签名串求签

byte[] bytes = null;

try {

MessageDigest md5 = MessageDigest.getInstance("MD5");

bytes = md5.digest(basestring.toString().getBytes("UTF-8"));

} catch (Exception ex) {

log.error("getSignature:" + params.toString(), ex);

}

###

// 将 MD5 输出的二进制结果转换为小写的十六进制

StringBuilder sign = new StringBuilder();

for (int i = 0; i < bytes.length; i++) {

String hex = Integer.toHexString(bytes[i] & 0xFF);

if (hex.length() == 1) {

sign.append("0");

}

sign.append(hex);

}

return sign.toString();

}

public static void addSignture(){

Arguments arguments = sampler.getArguments();

Map inMap = new HashMap();

int len=arguments.getArgumentCount();

for(int i=0;i<len;i++){

Argument jpro=arguments.getArgument(i);

String key=jpro.getName();

String ret=jpro.getValue();

inMap.put(key,ret);

}

String key= vars.get("Key");

String signresult=getSignature(inMap,key);

arguments.addArgument(new HTTPArgument("sign",signresult));

}

}

SignTest.addSignture();

二、JMeter 中 BeanShell PreProcessor 进行证书加密及解密的方法,代码如下:
加密:

String keySecret = "${appKey}";//secret

String encryptSignKey = "weiyankeji.cn";//加签 key

String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDARhN2p7W6qaR73dpgpr9vo";

log.info("\n\n===============start to encryt the params,"+vars.getClass());

try{

Map paramsTemp = new HashMap();

Map params = new HashMap();

Arguments arguments = sampler.getArguments();

int i = arguments.getArgumentCount();

for(int j=0;j<i;j++){

HTTPArgument arg = arguments.getArgument(j);

params.put(arg.getName(),arg.getValue());

}

String sign = Signature.sign(params, keySecret);

log.info("\n\n===============print the sign,"+sign);

params.put("sign", sign);

String paramsJson = JSON.toJSONString(params);

System.out.println("=====================paramsJson=======================");

System.out.println(paramsJson);

log.info("\n\n===============print the params,"+paramsJson);

byte[] encryptData = RSAUtils.encryptByPublicKey(paramsJson.getBytes(Charsets.UTF_8), publicKey.getBytes());

log.info("\n\n===============print the params,"+paramsJson);

paramsTemp.put("Id", "${Id}");

paramsTemp.put("timestamp", "${timestamp}");

paramsTemp.put("encryptType", "rsa");

paramsTemp.put("encrypt", new String(Base64Utils.encode(encryptData)));

String msgSignature = Signature.sign(paramsTemp, encryptSignKey);

paramsTemp.put("msgSignature", msgSignature);

log.info("\n\n=============== finished the paramstemp="+JSON.toJSONString(paramsTemp));

arguments.removeAllArguments();

for(Entry entry :paramsTemp.entrySet()){

arguments.addArgument(new HTTPArgument(entry.getKey(), entry.getValue()));

}

}

catch(Throwable ex){

log.error("===============Error in Beanshell", ex);

throw ex;

}

解密:

String sinatureKey = "wsdjljksfs";

log.info("\n\n===============start to decrypt the params,"+prev.getClass());

String result = prev.getResponseDataAsString();

String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKFGnds0H";

JSONObject responseObj = JSON.parseObject(result);

Map responseParams = Maps.newHashMap();

for (Map.Entry entry : responseObj.entrySet()) {

responseParams.put(entry.getKey(), String.valueOf(entry.getValue()));

}

responseParams.remove("msgSign");

String responseGenSign = Signature.sign(responseParams, sinatureKey);

log.info("\n\n===============sign to decrypt the params,"+responseGenSign);

if(! responseGenSign.equals(responseObj.getString("msgSign"))){

log.info("\n\n=============== sign failure=============================");

return;

}

log.info("\n\n===============start to decrypt the params,"+responseObj);

String responseEncrypt = responseObj.getString("encrypt");

byte[] decryptData = RSAUtils.decryptByPrivateKey(

Base64Utils.decode(responseEncrypt.getBytes(Charsets.UTF_8)),

privateKey.getBytes());

System.out.println("=====================response decrypt=======================");

System.out.println(new String(decryptData, Charsets.UTF_8));

log.info("\n\n===============end to decrypt the params,"+new String(decryptData, Charsets.UTF_8));

prev.setResponseData(new String(decryptData, Charsets.UTF_8));

共收到 2 条回复 时间 点赞
Flange 关闭了讨论 06月08日 10:03
Flange 重新开启了讨论 06月08日 10:03

代码排版用下 markdown 吧,https://testerhome.com/markdown

大佬 写完预览下 太丑了 没法看

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册