You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JMeter中BeanShell编写RSA/AES加解密代码报错问题

报错原因
  • 直接触发语法错误的是代码中的双引号全部被转义为HTML实体",BeanShell解释器无法识别该转义字符,解析到对应位置时会出现大括号匹配失败,最终抛出Encountered "}"的解析错误。
  • BeanShell是轻量级脚本解释器,不支持在脚本内声明package,也不需要将业务逻辑包裹在自定义的public class结构中,外层类的多余大括号会直接被判定为非法语法,加剧解析错误。
  • 现有代码存在隐性兼容问题:JDK自带的JCE组件默认不支持AES/CBC/PKCS7Padding加密模式,即使语法修正后,运行时也会抛出无对应加密算法的错误;另外现有generateIv方法生成的是全0固定IV,不符合CBC模式的安全规范,大概率和服务端加解密逻辑不匹配。
  • 现有代码未实现需求中要求的「RSA公钥加密随机串R1」的逻辑,无法直接完成完整加解密流程。
修正方案
  1. 移除原有代码中的package声明、外层Crypto类的包裹结构,将所有"替换为正常英文双引号。
  2. 引入BouncyCastle加密组件解决PKCS7Padding的支持问题,补充RSA加密R1的逻辑,修正IV生成逻辑为随机生成,最终可直接在BeanShell前置处理器/取样器中运行的代码如下:
import java.security.SecureRandom;
import java.util.Base64;
import java.util.UUID;
import java.security.KeyFactory;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.PublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;

// 注册BouncyCastle加密提供者
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
    Security.addProvider(new BouncyCastleProvider());
}

// 生成16位随机IV
static IvParameterSpec generateIv() {
    byte[] iv = new byte[16];
    new SecureRandom().nextBytes(iv);
    return new IvParameterSpec(iv);
}

// AES-CBC-PKCS7加密
static String aesEncrypt(String input, String secretKey, IvParameterSpec iv) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(secretKey.getBytes("UTF-8"), "AES"), iv);
    byte[] cipherText = cipher.doFinal(input.getBytes("UTF-8"));
    return Base64.getEncoder().encodeToString(cipherText);
}

// RSA公钥加密
static String rsaEncrypt(String plainText, String publicKeyStr) throws Exception {
    byte[] keyBytes = Base64.getDecoder().decode(publicKeyStr);
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.getBytes("UTF-8")));
}

// 生成32位随机密钥R1
String R1 = UUID.randomUUID().toString().replace("-", "");
IvParameterSpec iv = generateIv();
// 替换为自身业务的RSA公钥,需去掉头尾的BEGIN/END PUBLIC KEY标识,仅保留中间Base64字符串
String rsaPublicKey = "替换为实际RSA公钥";
// RSA加密R1
String encryptedKey = rsaEncrypt(R1, rsaPublicKey);
// 替换为实际待加密的请求体,可通过vars.get("变量名")引用JMeter中已存储的请求数据
String requestBody = "待加密请求体内容";
// AES加密请求体
String encryptedBody = aesEncrypt(requestBody, R1, iv);

// 将加密结果存入JMeter变量,后续请求可直接通过${变量名}引用
vars.put("encryptedKey", encryptedKey);
vars.put("iv", Base64.getEncoder().encodeToString(iv.getIV()));
vars.put("encryptedBody", encryptedBody);
注意事项
  • 需提前将对应版本的BouncyCastle jar包(命名格式为bcprov-jdk15on-xxx.jar)放入JMeter安装目录的lib文件夹下,放入后重启JMeter才可正常加载。
  • 代码中RSA加密的填充模式为PKCS1Padding,如果你的服务端使用其他填充模式,需对应修改Cipher.getInstance中的算法参数,和服务端逻辑保持一致。
  • 若追求更高的压测性能,建议将BeanShell替换为JSR223测试元件+Groovy语言,可避免BeanShell的解释执行性能损耗,语法兼容度也更高。

内容的提问来源于stack exchange,提问作者Bhavya Dutta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:18:21