jmeter二次开发函数---HmacSha256加密

网上查找HmacSha256加密算法:https://www.freesion.com/article/8988227191/

下载jmeter5.1.1源码,eclipse新建java project  ,创建项目后,在项目右侧点击导入,将源码导入项目,此时src下有错误,需要导入关联的lib。 将release版本下的lib全部复制到eclipse项目的lib下,刷新后src无报错。

在src/function下面添加HmacSha256.java,后在src/function点右键导出jar file,名称为jmeter_functions.jar,所有jmeter调用的函数都在此包中,放到release版本下的lib/ext中覆盖原有包,将原包备份。重启jmeter

 

 

HmacSha256.java

package org.apache.jmeter.functions;
import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.Sampler;
import org.apache.jmeter.threads.JMeterVariables;
import org.apache.jmeter.util.JMeterUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class HmacSha256 extends AbstractFunction{                    //所有定义的函数都要继承AbstractFunction

    
    private static final List<String> desc = new LinkedList<>();      //所有参数说明定义成数组
    private static final String KEY = "__HMAC-SHA256"; // Function name        //在函数中显示的函数名
 
    static {  
        desc.add(JMeterUtils.getResString("要加密的串")); // 函数助手中显示的参数说明,对应到参数  ,有几个入参就定义几个
        desc.add(JMeterUtils.getResString("盐"));
        desc.add(JMeterUtils.getResString("方法名"));// 保存函数返回结果的变量,用于引用  
    }
    private CompoundVariable param1, param2;              //入参需要定义成CompoundVariable,有几个入参就定义几个
    
    @Override
    public List<String> getArgumentDesc() {         //重写不变
        return desc;
    }
    
    public HmacSha256() {                      
    }
    
    private static final String MAC_NAME = "HmacSHA256";
    private static final String ENCODING = "UTF-8";
    @Override
    public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException {              //重写自定义函数,写到execute
    
        String encryptText=param1.execute().trim();                               //将方法的传入的参数转换成string 
        String encryptKey=param2.execute().trim();
        
        String hash = "";
        Mac mac = null;
        try {
            mac = Mac.getInstance(MAC_NAME);
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        SecretKeySpec secret_key = new SecretKeySpec(encryptKey.getBytes(), MAC_NAME);
        try {
            mac.init(secret_key);
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        byte[] bytes = mac.doFinal(encryptText.getBytes());
        hash = byteArrayToHexString(bytes);
        return hash;
        
    }
    

    /**
     * 使用 HMAC-SHA256 签名方法对encryptText进行签名
     *
     * @param encryptText 被签名的字符串
     * @param encryptKey  密钥
     * @return
     * @throws Exception
     */
    public static byte[] HmacSHA256Encrypt(String encryptText, String encryptKey) throws Exception {    //可以删除,与上面的方法实现功能一样,只是返回类型为byte[],execute返回类型为string
        byte[] data = encryptKey.getBytes(ENCODING);
        // 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
        SecretKey secretKey = new SecretKeySpec(data, MAC_NAME);
        // 生成一个指定 Mac 算法 的 Mac 对象
        Mac mac = Mac.getInstance(MAC_NAME);
        // 用给定密钥初始化 Mac 对象
        mac.init(secretKey);

        byte[] text = encryptText.getBytes(ENCODING);
        // 完成 Mac 操作
        return mac.doFinal(text);
    }
    
    /**
     * 将加密后的字节数组转换成字符串
     *
     * @param b 字节数组
     * @return 字符串
     */
    public static String byteArrayToHexString(byte[] b) {   //HMAC-SHA256加密方法中调用此方法
        StringBuilder hs = new StringBuilder();
        String stmp;
        for (int n = 0; b != null && n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0XFF);
            if (stmp.length() == 1)
                hs.append('0');
            hs.append(stmp);
        }
        return hs.toString();
    }

    @Override
    public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException {   //jmeter原有固定方法,用于检查参数数量
        // 检查参数数量
        checkParameterCount(parameters, 1, 2);
        Object[] values = parameters.toArray();
        
        param1 = (CompoundVariable) values[0];                   //param1取值values[0],有几个入参就定义几个
        if (values.length > 1){                                                 //当参数为可选参数,则使用if判断
            param2 = (CompoundVariable) values[1];
        } else {
            param2 = null;
        }
 
    }
 
    @Override
    public String getReferenceKey() {
        return KEY;
    }
}

 



posted @ 2020-05-29 11:09  lq430430  阅读(630)  评论(0)    收藏  举报