How to do mutual SSL authentication in java

Viewed 1965

I want to do mutual SSL authentication using java code but I didn't get success I have key.pem and cert.pem file to do authentication I have tried it with Curl

curl -X POST -d '{ "Channel": "....}' -H "Content-Type: application/json" -H "Auth1: ***" -H "Auth2: ***" -k https://******/webservices/JSON/Default.aspx --cert "cert.pem" --key "Key.pem"

and it was working fine then I trying to create java program reference Send https request in java using .pem file but server returns "CERT_MISSING". I also tried with this https://www.naschenweng.info/2018/02/01/java-mutual-ssl-authentication-2-way-ssl-authentication/ this code creating p12, crt and jks file as above link says but still getting same error "CERT_MISSING". This is working NodeJS example:

var https = require("https");
var fs = require("fs");

var jsonData = {
    "Channel": ....
}

var options = {
    hostname: "****",
    port: 443,
    path: '/webservices/JSON/Default.aspx',
    method: 'POST',
    timeout: this.TimeOut,
    headers: {'Content-Type':'application/json',"Auth1": "****","Auth2": "*****"},
    json: true,
    key: fs.readFileSync('Key.pem'),
    cert: fs.readFileSync('cert.pem')
}

var req = https.request(options, function(res) {
    res.on('data', function(data) {
        var response = JSON.parse(data)
            console.log(response)

            req.end();
    });
});
req.on('error', function(e) {
    console.log("ERROR:");

    })


req.write(JSON.stringify(jsonData));
req.end();

Please help me in this.

2 Answers

I think you need "internediate-cert" file to Concatenate all certificates into one PEM file Like cat "internediate-cert.pem" "codika_cert.pem" "Key.pem" > full-chain.keycert.pem then Generate the PKCS12(.p12) keystore with the alias and password Like pkcs12 -export -in "full-chain.keycert.pem" -out full-chain.keycert.p12 -name alias -noiter -nomaciter then use full-chain.keycert.p12 as KeyStore with password. It should work.

I'm just going to try to recall a few things to perhaps complete your checklist. I can't give a full example. I presume you control both client and server code. Or at least the client code, and full tuning of server config.

0-use wireshark to see what going on.

1-make sure your server side sends the accept-client-cert or requires-client-cert in the serverhello. Curl might be working only because the server isn't "requiring" it, only requesting it.

2-make sure your client cert signer will be trusted by the server. This means sometimes to hack the server's certificate authorities (CA) store if you will be making self-signed client cert when testing.

3-with wireshark, watch ssl/tls dialog and verify both clienthello and serverhello are as expected (mostly if serverhello does request/require client auth and if client even tries to send it). If anything, that is quite educative.

4-write trivial code using jsse tutorials from bottom up. make code kata to see the keystore/castore are there, contains what you expect. Then proceed with secure [server]socketfactory setup, keymanager, trustmanager and hostnameverifier (with or without the dangerous bypass of the later two some people dare suggest). When these 4 pieces are setup, you are 99% done and your ssl/tls socket should work. The few things that could typically still prevent your from a ssl/tls connection are incompatible cipher suite or tls version, or certs with invalid dates. Since you control both client and server, this should not be an issue.

5-once you can trust your client side behavior, you may try to connect to an https server like tomcat or jetty (I dont know what you use) and send a crude GET on the sslsocket with you java client.

6-When that works, now you can pass your sslsocketfactory to many http[s] stack (smtp, httplient, even core jdk httpurlconnection).

Related