Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenSSL and s_client - why is a private key required from the client?

I need to setup a 2 way SSL communication channel between a .NET/WCF application and a third party web server. Right now I am trying get a successful handshake with the host in order to validate that all the elements are setup correctly (client certificate, server certificate authority, network communication...). I'm using the openSSL command line tool to try and validate this, using the s_client command.

Here is what is stopping me, and what I don't understand:

  • whatever I do, openSSL is expecting to find a private key for the client certificate
  • the client certificate was given to me by the third party, but it does not contain any private key
  • if I just generate my own private key file using openSSL, I'm getting a key values mismatch error

Keep in mind that I have just started getting my hands into SSL so I have a very basic understanding of the whole protocol. From what I've been reading, it seems that both server and client need their private key in a 2 way SSL setting. However, I can't figure out how to get a working private key on my client (working with the client certificate that was given to me). I would very much appreciate if somebody could shed some light on client certificate private keys, as this is giving me a major headache.

like image 805
Aerendel Avatar asked Jun 26 '12 00:06

Aerendel


2 Answers

Certificates on their own are only public pieces of information. What links a public key certificate to the name it contains is the fact that whoever has legitimate control over that name (e.g. your name or your server's name) also has the private key for it.

Certificates are used to prove the identity of the remote party by challenging the remote party to perform an operation that can only be done with the corresponding private key: signing something (which can be verified with the public key) or deciphering something that was encrypted with the public key. (Both can happen in the SSL/TLS handshake, depending on the cipher suite.)

During the SSL/TLS handshake, the server sends its certificate (in clear) and proves to the client that it has the corresponding private key using an authenticated key exchange.

In your case, you also want to use client-certificate authentication. It's not enough to send the client certificate during the handshake: the client must also prove it has the private key. Otherwise, anyone who receives that certificate could clone it. The point of using certificates is to prevent any cloning, in such a way that you never have to show your own secret (the private key).

More specifically, the client has to sign the handshake messages in the Certificate Verify message of the TLS handshake so that the server can verify it against the public key sent in the client certificate. Without this step, no client-certificate authentication would be taking place.

the client certificate was given to me by the third party, but it does not contain any private key

Giving you your certificate without its private key seems a bit pointless, unless you're expected to have generated a certificate request on your side beforehand (in which case you would have the private key).

Indeed, rather than being given a certificate and its private key, it's better practice for you to generate your key-pair, create a certificate request (CSR), and have your CA issue a certificate from that CSR (but without them ever knowing your private key). In this case, you would be expected to have kept your private key, and you would be able to use it with the cert you would have received.

like image 191
Bruno Avatar answered Sep 19 '22 07:09

Bruno


This is an interesting question. I was puzzled by TLS related errors while configuring LDAPS, my learnings here.

  • The names, "public key" and "private key" sound like it's an one-way operations, but it works both ways, anything encrypted by one key and be decrypted by another key - just that one key is made public
  • Info = openly available data, with unknown integrity - it could be tampered by 3rd party
  • Signature = Info encrypted by a private key, accompanies Info
  • Verifying signature = use public key to decrypt the signature and get Info back thus proving "whoever created the signature knows the private key", or, the Info is untouched after it's signed
    • That is, unless the private key is stolen
  • Certificate = Info + Signature + public key + private key
    • Info = the meat
    • Signature = to verify integrity of Info
    • public key = to verify other certificates, see Certificate Chain
    • private key = not included in certificate itself but should be kept by certificate owner, could be used to sign other certificates
  • Certificate Authority (CA) = Anyone who holds a public / private key pair and creates certificates
    • CA identity is indicated in Info on a certificate
  • Certificate Chain = Use public key on mother-certificate to verify the signature on a child-certificate, to ensure child-certificate was created and signed by mother CA
    • And mother created and signed by grandma, so forth
  • Root CA = Root CA is the CA you trust unconditionally
    • Because their certificates (Root Certificates) are pre-loaded in your browser or OS as a source of trust
    • Also because their certificates are self-signed, its Signature is created using its own private key, verified by its own public key
    • This could be confusing, but think it as the origin of certificate-based encryption - only when people found out that relying on a few Root CA's to create and sign countless certificates are insecure (private keys might get stolen) and impossible (rapidly increasing demands of certificates), they came up with the idea of certificate chains
    • Root CA's only create and sign certificates for some Intermediate CA's so private keys are not used too often and is safer
    • Intermediate CA's can create and sign millions of certificates and get their certificate revoked when a private key is known to be leaked
    • This is the reason you don't often see the Root Key Ceremony, which signifies the importance of the private key for a Root Certificate: the less the private key is used, the less it could be exposed
  • Self-Signed Root Certificate = virtually the same as a Root Certificate - just no one but the creator would trust
  • TLS Handshake = server sends certificate, client validate is against the certificate chain, when verified, exchange a "password" securely
    • The "password" is then used to encrypt actual data transfer using symmetric encryption
    • Asymmetric encryption is not used for actual data due to its need for intense computation powers
  • Client Certificate Authentication = in addition to previous process which authenticates the server, the server demands a valid certificate to be provided by the client, also a signature of previous handshake messages
    • The signature is created using the private key of the certificate and can be verified by the public key on the certificate
    • This proves the ownership of the certificate
    • This is used usually for restricting access to known individual clients
    • Using certificates means no man-in-the-middle or replay attack could happen
    • This is often seen in finance or IoT
    • This is also utilized by LDAPS, which caused mystic error messages when I had a valid certificate in my local keystore but it was not accompanied by its private key

...So, in terms of openssl, when you use -cert you indicate Client Certificate Authentication, with which you will need -key to specify the corresponding private key.

However, for many Web scenarios, even if the certificate for a server is signed by a homemade CA, one only need to add the homemade CA to truststore or keychain then server certificate can be validated. This is done by using -CAfile.

like image 20
dz902 Avatar answered Sep 21 '22 07:09

dz902