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

在JMeter的JSR223预处理器中使用CryptoJS 4.0.0时出现原生加密模块错误的求助

在JMeter的JSR223预处理器中使用CryptoJS 4.0.0时出现原生加密模块错误的求助

我在JMeter的JSR223预处理器(基于ECMAScript 262 Edition 5.1引擎)里尝试使用CryptoJS 4.0.0做AES加密,代码如下:

load('C:/Users/hlopezgu/Downloads/crypto-js-4.0.0/crypto-js.js');

var key = 'secret key 123';

var textToEncrypt = '123456';

var encryptedText = CryptoJS.AES.encrypt(textToEncrypt, key).toString();

log.info("Texto cifrado: " + encryptedText);

运行后却遇到了错误:

Error: Native crypto module could not be used to get secure random number

我的需求是用这个库加密JSON中的数据,然后通过POST请求发送给Web服务,请问该怎么解决这个问题?


解决方案

这个错误的根源是CryptoJS 4.x版本依赖了Node.js的原生crypto模块生成安全随机数,但JMeter使用的Nashorn JavaScript引擎并没有这个模块,我们可以通过以下几种方式解决:

方案1:降级到CryptoJS 3.x版本

CryptoJS 3.x系列(比如3.3.0)不依赖原生crypto模块,完全用JavaScript实现了随机数生成逻辑。你不需要修改现有代码,只需要把加载的crypto-js.js替换成3.x版本的文件,就能直接运行原有代码,这是最简单的解决办法。

方案2:为CryptoJS添加自定义随机数生成器

如果必须使用4.0.0版本,可以手动为CryptoJS提供基于JavaSecureRandom的随机数生成器,替换它默认的依赖逻辑,修改后的代码如下:

load('C:/Users/hlopezgu/Downloads/crypto-js-4.0.0/crypto-js.js');

// 用Java的SecureRandom实现CryptoJS需要的随机数生成方法
CryptoJS.lib.WordArray.random = function(nBytes) {
    var secureRandom = new java.security.SecureRandom();
    var bytes = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, nBytes);
    secureRandom.nextBytes(bytes);
    var wordArray = CryptoJS.lib.WordArray.create();
    wordArray.sigBytes = nBytes;
    var words = wordArray.words;
    for (var i = 0; i < nBytes; i++) {
        words[i >>> 2] |= (bytes[i] & 0xff) << (24 - (i % 4) * 8);
    }
    return wordArray;
};

var key = 'secret key 123';
var textToEncrypt = '123456';
var encryptedText = CryptoJS.AES.encrypt(textToEncrypt, key).toString();
log.info("Texto cifrado: " + encryptedText);

这段代码通过Java的安全随机数生成器满足CryptoJS的需求,从而绕过对原生crypto模块的依赖。

方案3:直接使用Java加密API(推荐)

既然JMeter本身是Java应用,直接使用Java原生的加密API会更高效,也不需要引入外部JS库,而且生成的加密结果和CryptoJS默认格式完全兼容,示例代码如下:

importPackage(javax.crypto);
importPackage(javax.crypto.spec);
importPackage(java.nio.charset);

var key = 'secret key 123';
var textToEncrypt = '123456';

// 将原始密钥处理成AES要求的32字节密钥(通过SHA-256哈希)
var keyBytes = key.getBytes(StandardCharsets.UTF_8);
var md = java.security.MessageDigest.getInstance("SHA-256");
md.update(keyBytes);
var secretKey = new SecretKeySpec(md.digest(), "AES");

// 初始化AES加密器(CBC模式+PKCS5填充,自动生成随机IV)
var cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);

// 执行加密
var inputBytes = textToEncrypt.getBytes(StandardCharsets.UTF_8);
var encryptedBytes = cipher.doFinal(inputBytes);

// 组合IV和加密数据(和CryptoJS的输出格式一致)
var iv = cipher.getIV();
var combined = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, iv.length + encryptedBytes.length);
java.lang.System.arraycopy(iv, 0, combined, 0, iv.length);
java.lang.System.arraycopy(encryptedBytes, 0, combined, iv.length, encryptedBytes.length);

// 转成Base64字符串输出
var encryptedText = new sun.misc.BASE64Encoder().encode(combined);
log.info("Texto cifrado: " + encryptedText);

这个方案不需要依赖任何外部JS库,稳定性和性能都更适合JMeter的运行环境。


备注:内容来源于stack exchange,提问作者Hans López

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 08:48:09