作为一名资深接口测试工程师,我将详细解释在JMeter中使用Beanshell对接口参数进行RSA加密的步骤。RSA是一种非对称加密算法,加密公式为 c=memod nc = m^e \mod nc=memodn,其中:
- mmm 是明文参数
- ccc 是加密后的密文
- eee 和 nnn 是公钥的组成部分
整个过程需要公钥来加密参数(私钥用于解密,但接口测试中通常只涉及加密)。以下是结构化步骤,确保真实可靠,基于JMeter 5.x和Java标准库实现。
步骤1: 准备工作
- 获取公钥:从接口提供方获得RSA公钥,通常以Base64编码的字符串形式(如PEM格式)。示例:
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."。保存公钥到JMeter变量或文件。 - JMeter设置:确保JMeter已安装。添加HTTP请求组件(如HTTP Request)到测试计划,定义需要加密的参数(例如,参数名为
username)。 - Beanshell组件:Beanshell是JMeter的内置脚本引擎,支持Java语法。我们将用它编写加密代码。
步骤2: 添加Beanshell PreProcessor
在JMeter中,Beanshell PreProcessor用于在HTTP请求前执行加密逻辑:
- 右键点击HTTP请求组件 → Add → Pre Processors → BeanShell PreProcessor。
- 在名称栏输入描述,如“RSA加密参数”。
- 在脚本区域编写代码(下一步详细说明)。
步骤3: 编写Beanshell加密脚本
在Beanshell PreProcessor中,粘贴以下Java代码。代码使用javax.crypto包实现RSA加密:
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
try {
// 参数
String originalData = "需要加密的数据";
//公钥
String publicKeyStr = "你的公钥";
log.info("原始参数: " + originalData);
//log.info("原始数据长度: " + originalData.getBytes("UTF-8").length + " bytes");
// 处理公钥字符串
publicKeyStr = publicKeyStr.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replaceAll("\\s", "");
byte[] keyBytes = Base64.getDecoder().decode(publicKeyStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// 分段加密
byte[] dataBytes = originalData.getBytes("UTF-8");
int inputLen = dataBytes.length;
int maxEncryptBlock = 117; // RSA 1024位密钥的最大加密块大小
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > maxEncryptBlock) {
cache = cipher.doFinal(dataBytes, offSet, maxEncryptBlock);
} else {
cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * maxEncryptBlock;
}
byte[] encryptedBytes = out.toByteArray();
String encryptedParam = Base64.getEncoder().encodeToString(encryptedBytes);
// 存储加密后的参数
vars.put("encryptedParam", encryptedParam);
log.info("=== RSA加密结果 ===");
log.info("加密后参数: " + encryptedParam);
log.info("加密数据长度: " + encryptedParam.length());
log.info("分段加密次数: " + i);
} catch (Exception e) {
log.error("RSA加密失败: ", e);
}
关键说明:
- 公钥处理:公钥必须是标准格式(如X.509)。如果公钥是PEM文件,需先去除
-----BEGIN PUBLIC KEY-----等头尾标记,只保留Base64内容。 - 参数来源:
vars.get("username")假设参数值已通过其他方式(如CSV Data Set Config)设置到JMeter变量。如果没有,可直接赋值:String plainText = "test_user";。 - 加密模式:使用
RSA/ECB/PKCS1Padding确保兼容性,避免安全风险(如OAEP可能更安全,但PKCS#1更通用)。 - 错误处理:
try-catch块捕获异常,避免脚本失败导致测试中断。
步骤4: 在HTTP请求中使用加密参数
- 在HTTP请求组件中,将需要加密的参数值替换为加密后的变量:
- 参数名:保持原样(如
username)。 - 参数值:输入
${encrypted_username}(Beanshell脚本设置的变量)。
- 参数名:保持原样(如
- 确保其他参数(如URL、Method)正常配置。
步骤5: 测试和验证
- 运行测试:启动JMeter测试。Beanshell PreProcessor会自动在请求前加密参数。
- 验证加密:
- 添加View Results Tree监听器,检查请求详情。加密后的值应为Base64字符串(如
"aGVsbG8=...")。 - 使用外部工具(如OpenSSL)解密验证:
echo <密文> | base64 -d | openssl rsautl -decrypt -inkey private.pem,确保与原始参数一致。
- 添加View Results Tree监听器,检查请求详情。加密后的值应为Base64字符串(如
- 性能注意:Beanshell脚本可能影响性能。在高并发测试中,考虑使用JSR223 PreProcessor(Groovy脚本)替代,但语法类似。
常见问题解决
- 公钥错误:如果报错
InvalidKeyException,检查公钥格式。使用在线工具验证公钥有效性。 - 参数未更新:确保Beanshell PreProcessor在HTTP请求前执行,且变量名正确。
- 编码问题:明文参数使用
getBytes("UTF-8")避免中文乱码。
通过以上步骤,您可以可靠地在JMeter中实现RSA参数加密。如需进一步优化(如密钥动态加载),可扩展脚本逻辑。
2929

被折叠的 条评论
为什么被折叠?



