Client Authentication In Ssl
Mini tutorial for configuring client-side SSL certificates. gist:952344. Mini tutorial for configuring client-side SSL certificates. gist:952344. I use Nginx as reverse http proxy to more than one web servers. I need to configure the client certificate-based authentication only for some locations, not all the locations configured in. Client Certificate Authentication is a mutual certificate based authentication, where the client provides its Client Certificate to the Server to prove its identity. This happens as a part of the SSL Handshake (it is optional ). SSL Client Authentication Step By Step May 7, 2014 Dan 8 Comments SSL’s primary function on the Internet is to facilitate encryption and trust that allows a web browser to validate the authenticity of a web site.
I'm fairly new to HTTPS/SSL/TLS
and I'm a bit confused over what exactly the clients are supposed to present when authenticating with certificates.
I'm writing a Java client that needs to do a simple POST
of data to a particular URL
. That part works fine, the only problem is it's supposed to be done over HTTPS
. The HTTPS
part is fairly easy to handle (either with HTTPclient
or using Java's built-in HTTPS
support), but I'm stuck on authenticating with client certificates. I've noticed there's already a very similar question on here, which I haven't tried out with my code yet (will do so soon enough). My current issue is that - whatever I do - the Java client never sends along the certificate (I can check this with PCAP
dumps).
I would like to know what exactly the client is supposed to present to the server when authenticating with certificates (specifically for Java - if that matters at all)? Is this a JKS
file, or PKCS#12
? What's supposed to be in them; just the client certificate, or a key? If so, which key? There's quite a bit of confusion about all the different kinds of files, certificate types and such.
As I've said before I'm new to HTTPS/SSL/TLS
so I would appreciate some background information as well (doesn't have to be an essay; I'll settle for links to good articles).
6 Answers
Finally managed to solve all the issues, so I'll answer my own question. These are the settings/files I've used to manage to get my particular problem(s) solved;
The client's keystore is a PKCS#12 format file containing
- The client's public certificate (in this instance signed by a self-signed CA)
- The client's private key
To generate it I used OpenSSL's pkcs12
command, for example;
Tip: make sure you get the latest OpenSSL, not version 0.9.8h because that seems to suffer from a bug which doesn't allow you to properly generate PKCS#12 files.
This PKCS#12 file will be used by the Java client to present the client certificate to the server when the server has explicitly requested the client to authenticate. See the Wikipedia article on TLS for an overview of how the protocol for client certificate authentication actually works (also explains why we need the client's private key here).
The client's truststore is a straight forward JKS format file containing the root or intermediate CA certificates. These CA certificates will determine which endpoints you will be allowed to communicate with, in this case it will allow your client to connect to whichever server presents a certificate which was signed by one of the truststore's CA's.
To generate it you can use the standard Java keytool, for example;
Using this truststore, your client will try to do a complete SSL handshake with all servers who present a certificate signed by the CA identified by myca.crt
.
The files above are strictly for the client only. When you want to set-up a server as well, the server needs its own key- and truststore files. A great walk-through for setting up a fully working example for both a Java client and server (using Tomcat) can be found on this website.
Issues/Remarks/Tips
- Client certificate authentication can only be enforced by the server.
- (Important!) When the server requests a client certificate (as part of the TLS handshake), it will also provide a list of trusted CA's as part of the certificate request. When the client certificate you wish to present for authentication is not signed by one of these CA's, it won't be presented at all (in my opinion, this is weird behaviour, but I'm sure there's a reason for it). This was the main cause of my issues, as the other party had not configured their server properly to accept my self-signed client certificate and we assumed that the problem was at my end for not properly providing the client certificate in the request.
- Get Wireshark. It has great SSL/HTTPS packet analysis and will be a tremendous help debugging and finding the problem. It's similar to
-Djavax.net.debug=ssl
but is more structured and (arguably) easier to interpret if you're uncomfortable with the Java SSL debug output. It's perfectly possible to use the Apache httpclient library. If you want to use httpclient, just replace the destination URL with the HTTPS equivalent and add the following JVM arguments (which are the same for any other client, regardless of the library you want to use to send/receive data over HTTP/HTTPS):
Client Authentication In Ssl Download
tmbrggmntmbrggmnOther answers show how to globally configure client certificates.However if you want to programmatically define the client key for one particular connection, rather than globally define it across every application running on your JVM, then you can configure your own SSLContext like so:
They JKS file is just a container for certificates and key pairs.In a client-side authentication scenario, the various parts of the keys will be located here:
- The client's store will contain the client's private and public key pair. It is called a keystore.
- The server's store will contain the client's public key. It is called a truststore.
The separation of truststore and keystore is not mandatory but recommended. They can be the same physical file.
To set the filesystem locations of the two stores, use the following system properties:
and on the server:
To export the client's certificate (public key) to a file, so you can copy it to the server, use
To import the client's public key into the server's keystore, use (as the the poster mentioned, this has already been done by the server admins)
For those of you who simply want to set up a two-way authentication (server and client certificates), a combination of these two links will get you there :
Two-way auth setup:
You don't need to use the openssl config file that they mention; just use
$ openssl genrsa -des3 -out ca.key 4096
$ openssl req -new -x509 -days 365 -key ca.key -out ca.crt
to generate your own CA certificate, and then generate and sign the server and client keys via:
$ openssl genrsa -des3 -out server.key 4096
$ openssl req -new -key server.key -out server.csr
$ openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 100 -out server.crt
and
$ openssl genrsa -des3 -out client.key 4096
$ openssl req -new -key client.key -out client.csr
$ openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 101 -out client.crt
For the rest follow the steps in the link. Managing the certificates for Chrome works the same as in the example for firefox that is mentioned.
Next, setup the server via:
Note that you have already created the server .crt and .key so you don't have to do that step anymore.
I think the fix here was the keystore type, pkcs12(pfx) always have private key and JKS type can exist without private key. Unless you specify in your code or select a certificate thru browser, the server have no way of knowing it is representing a client on the other end.
protected by Community♦May 2 '17 at 22:38
Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
Not the answer you're looking for? Browse other questions tagged javasslhttpsclient-certificates or ask your own question.
HTTPS Client Authentication
HTTPS Client Authentication requires the client to possess a PublicKey Certificate (PKC). If you specify client authentication,the web server will authenticate the client using the client’s publickey certificate.
HTTPS Client Authentication isa more secure method of authentication than either basic or form-based authentication.It uses HTTP over SSL (HTTPS), in which the server authenticates the clientusing the client’s Public Key Certificate (PKC). Secure Sockets Layer(SSL) technology provides data encryption, server authentication, messageintegrity, and optional client authentication for a TCP/IP connection. Youcan think of a public key certificate as the digital equivalent of a passport.It is issued by a trusted organization, which is called a certificate authority(CA), and provides identification for the bearer.
Before using HTTP Client Authentication, you must make sure that thefollowing actions have been completed:
Make sure the client has a valid Public Key Certificate. Formore information on creating and using public key certificates, read Working with Digital Certificates.
Make sure that SSL support is configured for your server.If your server is the Sun GlassFishEnterprise Server v3, SSL support isalready configured. If you are using another server, consult the documentationfor that server for information on setting up SSL support. More informationon configuring SSL support on the application server can be found in Establishing a Secure Connection Using SSL and the Sun GlassFish Enterprise Server v3 Administration Guide.
The following example shows how to declare HTTPS client authenticationin your deployment descriptor:
An example demonstrating HTTPS client authentication may be availablein Part VII, Security, in The Java EE 6 Tutorial, Volume II.
Mutual Authentication
With mutual authentication, the server and theclient authenticate one another. There are two types of mutual authentication:
Certificate-based mutual authentication (see Figure 25–4)
User name- and password-based mutual authentication (see Figure 25–5)
A client requests access to a protected resource.
The web server presents its certificate to the client.
The client verifies the server’s certificate.
If successful, the client sends its certificate to the server.
The server verifies the client’s credentials.
If successful, the server grants access to the protected resourcerequested by the client.
When using certificate-based mutual authentication, the following actionsoccur:
Figure 25–4 shows what occursduring certificate-based mutual authentication.
Figure 25–4 Certificate-Based Mutual Authentication
A client requests access to a protected resource.
The web server presents its certificate to the client.
The client verifies the server’s certificate.
If successful, the client sends its user name and passwordto the server, which verifies the client’s credentials.
If the verification is successful, the server grants accessto the protected resource requested by the client.
In user name- and password-based mutual authentication, the followingactions occur:
Figure 25–5 shows what occursduring user name- and password-based mutual authentication.
Figure 25–5 User Name- and Password-Based Mutual Authentication
Comments are closed.