jmeter JSR223 preprocessor javascript 介面資訊加密

西夏一品唐發表於2024-08-03

在進行介面測試或壓測時,有時候需要對介面內容進行加密處理,否則伺服器會直接拒絕請求。以下透過jmeter引入cryptoJS包的方式來實現介面引數資訊的加密。

先下載javascript cryptoJS 包,將檔案複製到jmeterbin目錄中。

jmeter 前置處理器中新增JSR223 preProcessor,如:jmeter-> pre processor -> JSR223 preprocessor,選擇語言:javascript。

透過load(uri);載入cryptoJS的檔案,當前初始路徑為jmeterbin目錄。

定義引入的cryptoJS 變數。需要注意的是雖然JSR 223執行javascript語言,但是也不是全支援javascript語言。如定義變數關鍵字不支援:constlet之類的。因此定義變數儘可能用var 關鍵字。

定義好cryptoJS變數後,可根據實際介面的加密方式,進行相關指令碼的設計。

以下是jmeter javascripthmac256加密程式碼示例及說明僅供參考:

load("./crypto-js/crypto-js.js");

// 定義引入的cryptoJS變數
var CryptoJS = CryptoJS;
var timestamp=getTimestamp();
var randomNum = getRandomInt(1,10);
var nonce = getMD5();
log.info(timestamp);
log.info(randomNum);

// 生成時間戳且擷取保留10位長度
function getTimestamp(){
    var timestamp = (Date.now()/1000).toString().substring(0,10);
    return timestamp;
    }

//生成15位0-9的隨機數
function getRandomInt(min,max){
    min = Math.ceil(min);
    max = Math.floor(max);
    nodeNum = "";
    for(var i=1;i<=15;i++){
        nodeNum+=Math.floor(Math.random()*(max-min+1))+min;
        }
    return nodeNum;
    }
//透過md5加密時間戳和隨機數
function getMD5(){
    message = timestamp+getRandomInt
    md5Hash=CryptoJS.MD5(message).toString();
    return md5Hash;
    }

//Hmac256的加密方法
function cryptoHmac(data,key){
    return CryptoJS.HmacSHA256(data,key).toString();
    }

var method = sampler.getMethod();  //獲取當前的請求方法
var path = sampler.getPath();          //獲取當前請求的path路徑資訊
var find_char1 = path.indexOf("?");  //確認path路徑中是否存在引數
var find_char2 = path.indexOf("="); // 確認path路徑中是否存在引數
var body_obj = sampler.getArguments();  //獲取當前請求引數的物件值
var params_num = body_obj.getArgumentCount();  // 獲取當前請求的引數數量
var body_params = "";

log.info(params_num);
//透過請求方法和path路徑找到引數值
if(method.toUpperCase() == "GET" && find_char1>0 && find_char2>0){
    body_params = path.substr(find_char1+1);
}else if(method.toUpperCase() == "POST" && params_num ==1){
    log.info("debug");
    body_params = body_obj.getArgument(0).getValue();
    
}else if(method.toUpperCase() == "POST" && params_num>1){
    body_params = ""
    for(var i=0;i<params_num;i++){
        body_params+=body_obj.getArgument();
        }
}else{
    log.info("無有效引數!");    
    }


var secretKey = nonce+"//"+"jkdfsnkkkalslbcmsaad";
//var body_params = body_value.getArgument(0).getValue();
var hmac_value = cryptoHmac(body_params,secretKey);  //獲取加密後的內容
log.info(hmac_value)
var sample_header_obj = sampler.getHeaderManager();
log.info(sample_header_obj);
log.info(sample_header_obj.size());

//將加密相關的資訊新增到當前的請求頭中
sample_header_obj.add(new org.apache.jmeter.protocol.http.control.Header("Sec-Fetch-timestamp",timestamp));
sample_header_obj.add(new org.apache.jmeter.protocol.http.control.Header("Sec-Fetch-nonce",nonce));
sample_header_obj.add(new org.apache.jmeter.protocol.http.control.Header("auth",hmac_value));
sample_header_obj.add(new org.apache.jmeter.protocol.http.control.Header("Sec-Fetch-Mode","sk"));

//將body的引數內容替換為加密後的內容
if(method.toUpperCase() == "POST" && params_num ==1){
    log.info("dfsfdsfdsfds");
    var new_body_params = cryptoHmac(body_params,secretKey);
    body_obj.getArgument(0).setValue(new_body_params);    
}

實際執行結果:

在執行結果數中的引數資訊:

在執行結果數中的請求頭資訊

相關文章