0

In my application I've successfully implemented client authentication using X509 certificates

Here's what I've done:

  1. Issued a self-signed CA root certificate with a private key
  2. Issued a web-server certificate with a private key and signed it with the root one
  3. Issued a client certificate with a private key and signed it with the root one

I converted the client's certificate into a .p12 (from what I can gather, this extension allows to incorporate a certificate with a private key into a single file)

Finally, I imported the client's .p12 and the root CA self-signed certificate (CSU) into my OS like so (I also set the trust setting to the self-signed root CA to "Always Trust"):

enter image description here

The final step was to configure nginx. I used the following configuration:

listen        443 ssl;

ssl_certificate     /usr/local/etc/nginx/ssl/testcasignedsrv/x509-server.crt; // server's certificate
ssl_certificate_key /usr/local/etc/nginx/ssl/testcasignedsrv/x509-server.key; // server's private key

ssl_client_certificate /usr/local/etc/nginx/ssl/testcasignedsrv/ca.crt; // self-signed CA that signed the client's and server's certificates, "CSU" in this case
ssl_verify_client on; // enables client's authentication

When I go to the URL of my local web-server in Chrome, I'm prompted to choose the certificate as expected.

enter image description here

After I select the certificate the authentication succeeds as expected and I'm finally authenticated on the server.

However, I can't figure out how it works internally, so I have some questions:

  1. Am I making an authentication request by signing something like a message with the private key of the client's certificate by clicking on "OK" in the browser?
  2. What field from the certificate is used to authenticate the user?
  3. How does the server verify that the client claims who they are? I mean how does it know that the client's certificate has been signed by the CA and trustworthy?
  4. I used to have more certificates linked with private keys in my KeyChain (cleaned it up recently). But the thing is that only the "right" ones (the ones that were signed by the appropriate CA) were displayed in the browser for authentication at a particular resource. How does the browser figure it out?

1 Answer 1

1

Am I making an authentication request by signing something like a message with the private key of the client's certificate by clicking on "OK" in the browser?

The client indeed signs all the previous messages of the current TLS handshake using its private key in order to authenticate itself.

References: TLS v1.2, TLS v1.3.

The client authentication mechanism actually depends on the type of client private key and certificate but you in practice, signing is (mostly) always used for client authentication in practice. The alternative is to use a static client Diffie-Hellman public key but this option is deprecated and has not been used much in practice AFAIU.

How does the server verify that the client claims who they are? I mean how does it know that the client's certificate has been signed by the CA and trustworthy?

The client sends its client certificate to the server. The name of the CA is indicated in the certificate (issuer of the client certificate). The server has the public key of the CA (subjectPublicKeyInfo of the CA certificate). The server checks the signature of the client certificate (signature) using the public key found in the CA certificate.

I used to have more certificates linked with private keys in my KeyChain (cleaned it up recently). But the thing is that only the "right" ones (the ones that were signed by the appropriate CA) were displayed in the browser for authentication at a particular resource. How does the browser figure it out?

The server advertises the name of the CA(s) it supports in the certificate_authorities field of the CertificateRequest message (in TLS 1.2) or in the certificate authorities extension of the [CertificateRequest message](https://datatracker.ietf.org/doc/html/rfc8446#section-4.3.2 (in TLS 1.3). In practice, you server includes the name of the CA found in the /usr/local/etc/nginx/ssl/testcasignedsrv/x509-server.crt certificate. The client uses this information to select which client certificates can be used to authenticate on this server.

2
  • Thank you for your answer. So the private key of the client's certificate is not used explicitly when the web-server verifies the client?
    – Joe D
    Jan 25 at 13:18
  • Or maybe "the message" that has been signed (when "OK" is clicked) with the client's private key is verified using the public key of CA? I don't know, it makes more sense...
    – Joe D
    Jan 25 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.