Reputation: 15
I want to expose a service via an API with two factors of authentication using PHP/MySQL. One factor is a simple user name and password. For the other factor, I am attempting to use mutual TLS, in which the client certificate is matched with the username. I intend to use self-signed certificates from a CA I set up on a CentOS box with Apache and issue the client certificates to customers via a secure channel, along with the private keys.
I found some decent articles on how to set up user authentication using SSL certificates. The best I found so far is below.
https://cweiske.de/tagebuch/ssl-client-certificates.htm
But, there seems to be a hole this and the other articles in terms of explaining something to me. How I envision this working is that when a POST request is made by the client, along with the user name and password, a certificate with a digital signature signed by the private key issued to the user is also included. This signature can then be decrypted by the public key to confirm that the owner of the private key sent the message. But, these articles don't actually confirm that this is what is happening.
Instead, they say that Apache confirms the certificate was signed by the CA Cert. They also explain how to use PHP to access the fields in the certificate, such as SSL_CLIENT_S_DN_Email and SSL_CLIENT_M_SERIAL, and use them to confirm the certificate belongs to the sender of the message. But, it is not clear to me that they are not just using information in the public certificate. So, anyone who can access the public certificate can then use it as one of the factors of authentication to authenticate to the service. If so, this means it is not really a factor of authentication.
Am I mistaken to think what I hope is the case - that the certificate included with the message does include a signature signed by the private key issued to the user and that Apache decrypts the signature with the public key rather than just confirm the certificate was issued by the CA?
Upvotes: 0
Views: 3614
Reputation: 12515
There are two points.
In cases like that (client authentication by certificate) the server either maintains a list of certificates it trusts or CAs signing those certificates. A check will be made by the server that the certificate presented is in one of these two cases.
As for the certificate presented, not anyone can present any certificate, because the TLS exchange will mandate the client to do something with the associated private key, hence the server will be able to verify the client has indeed the relevant private key for the public certificate presented.
This is well explained at: https://en.wikipedia.org/wiki/Transport_Layer_Security#Client-authenticated_TLS_handshake which I summarize here:
Of course this all work only if you filter the end client certificates: if you allow any of them, anyone can create one with any identity that will work.
Upvotes: 1
Reputation: 370
Configuring Apache to allow mutual authentication is quite simple and the documentation on http://httpd.apache.org is quite clear. Basically you need two certificates: the server one to install on the Apache server and then the client one, to be installed on your Firefox browser or client application or other device. The client certificate must be issued by one of the CAs that the Apache server knows for authentication to succeed.
This project https://github.com/amusarra/docker-apache-ssl-tls-mutual-authentication implements a complete configuration of Apache SSL / TLS Mutual Authentication
Upvotes: 0