I've struggled one day but without luck. Googling can find few but often outdated answers.
My goal is using jmeter built in elements to send https request with client certificate. Think of some oauth server that validates the client certificate other than password.
I know writing my own plugin, or use some beanshell, etc, is possible. but I searched and found jmeter has built in Keystore Config Element so I decide to have a try.
First I setup my mock server, https://leiyang.icu:5001/home, an asp.net core website, which validates the clients has sent a certificate. It simply accepts GET
at path /home
, with optional query parameter location
. If client sends request with any certificate, it will response the location
value and the client certificate information as string, otherwise connection will abort(TODO: response some friendly message instead).
This is a working python client script to validate the server:
import requests
resp = requests.get('https://leiyang.icu:5001/home',
# if not specify cert, connection will be aborted by the server
cert=('pathto/any.crt',
'pathto/any.key'),
params={'location': 'fromrequests'}
)
print(resp.text)
output:
location=fromrequests cert=[Subject] CN={domain of client}
[Issuer] CN=Encryption Everywhere DV TLS CA - G1,
OU=www.digicert.com, O=DigiCert Inc, C=US
... and several other lines about the certificate
Now my steps to use jmeter as client:
Download jmeter 5.4.1 on my win10 with jdk 11, unzip.
In
bin
folder,
2.1 editsystem.properties
, set
javax.net.ssl.keyStore={mykeypath}
javax.net.ssl.keyStorePassword={thepwd}
2.2 editjmeter.properties
set
https.use.cached.ssl.context=false
Launch jmeter GUI, new a plan, add
csv data set config
,key store config
,http request sampler
,view results tree element
as the manuals guide. (It's to lengthy to put all details here, but I'll put some runtime logs later).Run the sampler. All requests failed(org.apache.http.NoHttpResponseException: leiyang.icu:5001 failed to respond) due to certificate issue. If change server code to not check certificate, then all requests pass.
Now some investigations:
Jmeter log.
021-07-07 22:31:21,481 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2021-07-07 22:31:21,482 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2021-07-07 22:31:21,484 INFO o.a.j.c.KeystoreConfig: Configuring Keystore with (preload: 'True', startIndex: 0, endIndex: -1, clientCertAliasVarName: 'cv')
2021-07-07 22:31:21,485 INFO o.a.j.u.SSLManager: JmeterKeyStore Location: C:/Users/myname/Downloads/cert/cert.p12 type pkcs12
2021-07-07 22:31:21,485 INFO o.a.j.u.SSLManager: KeyStore created OK
2021-07-07 22:31:21,485 WARN o.a.j.u.SSLManager: No password provided, and no GUI present so cannot prompt
2021-07-07 22:31:21,494 INFO o.a.j.u.SSLManager: Total of 1 aliases loaded OK from keystore C:/Users/myname/Downloads/cert/cert.p12
2021-07-07 22:31:21,494 INFO o.a.j.g.u.JMeterMenuBar: setRunning(true, local)
2021-07-07 22:31:21,524 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Thread Group
2021-07-07 22:31:21,524 INFO o.a.j.e.StandardJMeterEngine: Starting 1 threads for group Thread Group.
2021-07-07 22:31:21,524 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2021-07-07 22:31:21,524 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=1 ramp-up=1 delayedStart=false
2021-07-07 22:31:21,525 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2021-07-07 22:31:21,526 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2021-07-07 22:31:21,528 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-1
2021-07-07 22:31:21,528 INFO o.a.j.s.FileServer: Stored: t.csv
2021-07-07 22:31:21,892 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-1
2021-07-07 22:31:21,892 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-1
2021-07-07 22:31:21,893 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2021-07-07 22:31:21,893 INFO o.a.j.s.FileServer: Close: t.csv
2021-07-07 22:31:21,893 INFO o.a.j.c.KeystoreConfig: Destroying Keystore
2021-07-07 22:31:21,893 INFO o.a.j.g.u.JMeterMenuBar: setRunning(false, local)
In Key Store, I set the
Variable name holding certificate alias
field tocv
, and in thehttp sampler/parames
tab I added parameterlocation=${cv}
with same variable name as cert aliascv
, and inresults tree/request
tab, I can seeGET https://leiyang.icu:5001/home?location=myalias
, which means the variable is correctly assigned.I had use
keytool -v -list -storetype pkcs12 -keystore mycert.p12
to check the alias, is same as that in jmeter variable(cv
)In
http sampler/parames/sdvanced
tab, I have chosenimplementation
asHttpClient4
.The log doesn't contain any information about the certificate is actually used by http client, and even if put some wrong alias to the variable, nothing different happens in log.
So what's the problem, am I miss something? Could you give me any diagnosis suggestions?
Update:
I just tried exactly same steps with jmeter 4.0(with java8), and it's working!
So I doubt whether this is an issue of jmeter 5(with jdk11).