jmeter jsr223 PreProcessor 报错:java.security.InvalidKeyException: Missing key encoding
运行代码:
import javax.crypto.Cipher
import java.security.KeyFactory
import java.security.spec.X509EncodedKeySpec
import java.util.Base64
import java.net.URLEncoder
try {
// 配置参数
def RSA_PUB_KEY = vars.get("publicKey") ?: ""
def KEY_ALGORITHM = "RSA"
def MAX_ENCRYPT_BLOCK = 117
// 输入数据
def uname = vars.get("username") ?: ""
def pword = "jx@dev123"
// 或从变量获取: vars.get("pword") ?: "jx@dev123"
// 首先清理和验证公钥
def cleanPublicKey = RSA_PUB_KEY
.replaceAll("-----BEGIN PUBLIC KEY-----", "")
.replaceAll("-----END PUBLIC KEY-----", "")
.replaceAll("\\s", "").trim()
// 验证Base64格式
if (cleanPublicKey.length() % 4 != 0) {
int padding = 4 - (cleanPublicKey.length() % 4)
cleanPublicKey += "=" * padding
}
// 加密方法
def encryptByPublicKey = { byte[] data, String publicKey ->
byte[] keyBytes = Base64.decoder.decode(publicKey)
// 调试输出 - 检查解码后的密钥长度
log.info("Decoded key length: " + keyBytes.length)
try {
def x509KeySpec = new X509EncodedKeySpec(keyBytes)
def keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
def publicK = keyFactory.generatePublic(x509KeySpec)
// 配置加密器
def cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding")
cipher.init(Cipher.ENCRYPT_MODE, publicK)
// 分段加密处理
int inputLen = data.length
def out = new ByteArrayOutputStream()
int offSet = 0
int i = 0
while (inputLen - offSet > 0) {
int blockSize = (inputLen - offSet > MAX_ENCRYPT_BLOCK) ?
MAX_ENCRYPT_BLOCK : (inputLen - offSet)
byte[] cache = cipher.doFinal(data, offSet, blockSize)
out.write(cache, 0, cache.length)
i++
offSet = i * MAX_ENCRYPT_BLOCK
}
def encryptedData = out.toByteArray()
out.close()
return encryptedData
} catch (IllegalArgumentException e) {
log.error("密钥处理失败: " + e.getMessage())
throw e
}
}
// 执行加密
def resultU = Base64.encoder.encodeToString(encryptByPublicKey(uname.getBytes("UTF-8"), cleanPublicKey))
resultU = URLEncoder.encode(resultU, "UTF-8")
def resultP = Base64.encoder.encodeToString(encryptByPublicKey(pword.getBytes("UTF-8"), cleanPublicKey))
resultP = URLEncoder.encode(resultP, "UTF-8")
// 存储结果
vars.put("encryptedAccount", resultU)
vars.put("encryptedPassword", resultP)
log.info("加密成功 - Account: ${resultU.take(20)}... Password: ${resultP.take(20)}...")
} catch (IOException e) {
log.error("加密失败: ${e.getClass().getName()} - ${e.getMessage()}", e)
//SampleResult.setStopTest(true)
e.printStackTrace()
}
报错信息如下:
ERROR o.a.j.m.JSR223PreProcessor: Problem in JSR223 script, JSR223 PreProcessor
javax.script.ScriptException: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: Missing key encoding
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:320) ~[groovy-jsr223-3.0.20.jar:3.0.20]
at org.codehaus.groovy.jsr223.GroovyCompiledScript.eval(GroovyCompiledScript.java:71) ~[groovy-jsr223-3.0.20.jar:3.0.20]
at javax.script.CompiledScript.eval(Unknown Source) ~[?:1.8.0_351]
at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:230) ~[ApacheJMeter_core.jar:5.6.3]
at org.apache.jmeter.modifiers.JSR223PreProcessor.process(JSR223PreProcessor.java:45) [ApacheJMeter_components.jar:5.6.3]
at org.apache.jmeter.threads.JMeterThread.runPreProcessors(JMeterThread.java:983) [ApacheJMeter_core.jar:5.6.3]
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:561) [ApacheJMeter_core.jar:5.6.3]
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:501) [ApacheJMeter_core.jar:5.6.3]
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:268) [ApacheJMeter_core.jar:5.6.3]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_351]
Caused by: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: Missing key encoding
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(Unknown Source) ~[?:1.8.0_351]
at java.security.KeyFactory.generatePublic(Unknown Source) ~[?:1.8.0_351]
at java_security_KeyFactory$generatePublic$0.call(Unknown Source) ~[?:?]
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) ~[groovy-3.0.20.jar:3.0.20]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) ~[groovy-3.0.20.jar:3.0.20]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139) ~[groovy-3.0.20.jar:3.0.20]
at Script1$_run_closure1.doCall(Script1.groovy:40) ~[?:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_351]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_351]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_351]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_351]
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107) ~[groovy-3.0.20.jar:3.0.20]
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323) ~[groovy-3.0.20.jar:3.0.20]
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:274) ~[groovy-3.0.20.jar:3.0.20]
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1030) ~[groovy-3.0.20.jar:3.0.20]
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:38) ~[groovy-3.0.20.jar:3.0.20]
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47) ~[groovy-3.0.20.jar:3.0.20]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125) ~[groovy-3.0.20.jar:3.0.20]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:148) ~[groovy-3.0.20.jar:3.0.20]
at Script1.run(Script1.groovy:72) ~[?:?]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317) ~[groovy-jsr223-3.0.20.jar:3.0.20]
... 9 more