2

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:

  1. Download jmeter 5.4.1 on my win10 with jdk 11, unzip.

  2. In bin folder,
    2.1 edit system.properties, set
    javax.net.ssl.keyStore={mykeypath}
    javax.net.ssl.keyStorePassword={thepwd}
    2.2 edit jmeter.properties set
    https.use.cached.ssl.context=false

  3. 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).

  4. 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 to cv, and in the http sampler/parames tab I added parameter location=${cv} with same variable name as cert alias cv, and in results tree/request tab, I can see GET 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 chosen implementation as HttpClient4.

  • 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).

Lei Yang
  • 3,970
  • 6
  • 38
  • 59

0 Answers0