Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Mini tutorial for configuring client-side SSL certificates.

Client-side SSL

For excessively paranoid client authentication.

Using self-signed certificate.

Create a Certificate Authority root (which represents this server)

Organization & Common Name: Some human identifier for this server CA.

openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt

Create the Client Key and CSR

Organization & Common Name = Person name

openssl genrsa -des3 -out client.key 4096
openssl req -new -key client.key -out client.csr
# self-signed
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt

Convert Client Key to PKCS

So that it may be installed in most browsers.

openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12

Convert Client Key to (combined) PEM

Combines client.crt and client.key into a single PEM file for programs using openssl.

openssl pkcs12 -in client.p12 -out client.pem -clcerts

Install Client Key on client device (OS or browser)

Use client.p12. Actual instructions vary.

Install CA cert on nginx

So that the Web server knows to ask for (and validate) a user's Client Key against the internal CA certificate.

ssl_client_certificate /path/to/ca.crt;
ssl_verify_client optional; # or `on` if you require client key

Configure nginx to pass the authentication data to the backend application:

Using CACert Keys

@arr2036

This comment has been minimized.

Show comment
Hide comment
@arr2036

arr2036 Nov 4, 2012

Top tip for those signing client certs with an intermediary CA, you must cat rootca.pem >> intermediaryca.pem else nginx will return a very unhelpful 400 error.

arr2036 commented Nov 4, 2012

Top tip for those signing client certs with an intermediary CA, you must cat rootca.pem >> intermediaryca.pem else nginx will return a very unhelpful 400 error.

@jacobbrunson

This comment has been minimized.

Show comment
Hide comment
@jacobbrunson

jacobbrunson Aug 3, 2013

Thank you, this helped me after a lot of searching.

Thank you, this helped me after a lot of searching.

@lucdig

This comment has been minimized.

Show comment
Hide comment
@lucdig

lucdig Mar 26, 2015

Hello, 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 nginx.

How can I do?
Can I put the lines:

ssl_client_certificate /path/to/ca.crt;
ssl_verify_client optional;

inside the "location" definition?

Thnks a lot, regards
Luca

lucdig commented Mar 26, 2015

Hello, 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 nginx.

How can I do?
Can I put the lines:

ssl_client_certificate /path/to/ca.crt;
ssl_verify_client optional;

inside the "location" definition?

Thnks a lot, regards
Luca

@justabaka

This comment has been minimized.

Show comment
Hide comment
@justabaka

justabaka Mar 31, 2015

@lucdig, those lines belong to the server block along wih another SSL directives: https://gist.github.com/konklone/6532544

@lucdig, those lines belong to the server block along wih another SSL directives: https://gist.github.com/konklone/6532544

@jhmartin

This comment has been minimized.

Show comment
Hide comment
@jhmartin

jhmartin May 11, 2015

@lucdig SSL handshaking occurs prior to the server knowing any details about the request, so it will be a global rather than specific to a particular location.

@lucdig SSL handshaking occurs prior to the server knowing any details about the request, so it will be a global rather than specific to a particular location.

@developerworks

This comment has been minimized.

Show comment
Hide comment
@developerworks

developerworks Oct 8, 2015

Issues:

  1. One client certificate could be used for multiple users ? ( Distribute the client certificate to multiple user)
  2. If i want to let every user to use unique client certificate, I have to generate a client certificate for every user ?

Issues:

  1. One client certificate could be used for multiple users ? ( Distribute the client certificate to multiple user)
  2. If i want to let every user to use unique client certificate, I have to generate a client certificate for every user ?
@risacher

This comment has been minimized.

Show comment
Hide comment
@risacher

risacher Nov 12, 2015

@lucdig @jhmartin RFC 5746 specifies extensions to TLS that allow secure renegotiation, so it's not quite correct to say that requiring client certs must happen at the global level. Apache, for example can require client certs on a per-location basis. That said, nginx does not, and will not for the foreseeable future. The feature has been previously requested and categorized as 'wontfix'; see https://trac.nginx.org/nginx/ticket/317 and https://trac.nginx.org/nginx/ticket/498

@lucdig @jhmartin RFC 5746 specifies extensions to TLS that allow secure renegotiation, so it's not quite correct to say that requiring client certs must happen at the global level. Apache, for example can require client certs on a per-location basis. That said, nginx does not, and will not for the foreseeable future. The feature has been previously requested and categorized as 'wontfix'; see https://trac.nginx.org/nginx/ticket/317 and https://trac.nginx.org/nginx/ticket/498

@jacobalberty

This comment has been minimized.

Show comment
Hide comment
@jacobalberty

jacobalberty Nov 16, 2015

@risacher @lucdig @jhmartin it is however pretty easy to simply set ssl verification to optional and then just error unauthenticated users under certain locations while allowing them anywhere else.

@risacher @lucdig @jhmartin it is however pretty easy to simply set ssl verification to optional and then just error unauthenticated users under certain locations while allowing them anywhere else.

@ddacunha

This comment has been minimized.

Show comment
Hide comment
@ddacunha

ddacunha Oct 14, 2016

Thanks for the instructions.
I had to use client.pem for it to work.

ssl_client_certificate /path/to/client.pem;
ssl_verify_client optional; # or `on` if you require client key

Thanks for the instructions.
I had to use client.pem for it to work.

ssl_client_certificate /path/to/client.pem;
ssl_verify_client optional; # or `on` if you require client key
@fercho-ayala

This comment has been minimized.

Show comment
Hide comment
@fercho-ayala

fercho-ayala Dec 2, 2016

It works as expected. I used client.pfx instead of client.p12. Also, I used this with a Dropwizard framework, I generated a .jks file from .pfx file using the next command:

keytool -importkeystore -srckeystore client.pfx \
        -srcstoretype PKCS12 \
        -destkeystore client.jks \
        -deststoretype JKS

fercho-ayala commented Dec 2, 2016

It works as expected. I used client.pfx instead of client.p12. Also, I used this with a Dropwizard framework, I generated a .jks file from .pfx file using the next command:

keytool -importkeystore -srckeystore client.pfx \
        -srcstoretype PKCS12 \
        -destkeystore client.jks \
        -deststoretype JKS
@michelde

This comment has been minimized.

Show comment
Hide comment
@michelde

michelde Jan 7, 2017

Thank you, this helped me after a lot of searching.

michelde commented Jan 7, 2017

Thank you, this helped me after a lot of searching.

@RSchlenker

This comment has been minimized.

Show comment
Hide comment
@RSchlenker

RSchlenker Jan 16, 2017

Hey guys,
I would like to repeat the question asked by @developerworks
Is it possible to have different client certificates for one and the same server certificate? They could get for example a different CN to identify each user respectively.
Is a setup like this possible?
Kind regards,
RSchlenker

Hey guys,
I would like to repeat the question asked by @developerworks
Is it possible to have different client certificates for one and the same server certificate? They could get for example a different CN to identify each user respectively.
Is a setup like this possible?
Kind regards,
RSchlenker

@jchevali

This comment has been minimized.

Show comment
Hide comment
@jchevali

jchevali Mar 17, 2017

Thank you, this helped me after a lot of searching.

Thank you, this helped me after a lot of searching.

@GuidoThomassen

This comment has been minimized.

Show comment
Hide comment
@GuidoThomassen

GuidoThomassen May 19, 2017

Thanks, this was very useful! 👍

Thanks, this was very useful! 👍

@prbreezy

This comment has been minimized.

Show comment
Hide comment
@prbreezy

prbreezy Jun 14, 2017

Works like a charm!

Works like a charm!

@NeetishPathak

This comment has been minimized.

Show comment
Hide comment
@NeetishPathak

NeetishPathak Jun 21, 2017

what's the openssl API to ask for client side certificates from the server application. As I understand, client side authentication will not take place until server explicitly asks for it using the CertificateRequest message

what's the openssl API to ask for client side certificates from the server application. As I understand, client side authentication will not take place until server explicitly asks for it using the CertificateRequest message

@josejaguirre

This comment has been minimized.

Show comment
Hide comment
@josejaguirre

josejaguirre Aug 23, 2017

You are awesome 👍

You are awesome 👍

@storrgie

This comment has been minimized.

Show comment
Hide comment
@storrgie

storrgie Oct 29, 2017

@jacobalberty do you have an example of how to check verification in locations with nginx?

@jacobalberty do you have an example of how to check verification in locations with nginx?

@jango

This comment has been minimized.

Show comment
Hide comment
@jango

jango Nov 5, 2017

Here is a helpful command to figure out if the client certificate will verify correctly: openssl verify -verbose -CAfile ca.crt client.crt

Also, if you get error 18 at 0 depth lookup: self signed certificate it's due to the fact that you use the same Organization Name for both your ca and your client certificate.

jango commented Nov 5, 2017

Here is a helpful command to figure out if the client certificate will verify correctly: openssl verify -verbose -CAfile ca.crt client.crt

Also, if you get error 18 at 0 depth lookup: self signed certificate it's due to the fact that you use the same Organization Name for both your ca and your client certificate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment