Search code examples
authenticationsocketssslcertificatemutual-authentication

How does sending client certificate not expose the client to impersonation


Alright so I will be referring to this picture for ease of communicationdescription of TLS mutual authentication

Ok so the server sends a public key, which the client uses to encrypt its own certificate info to send back to the server. What I do not understand is why an attacker could not intercept the packet from step 4, and then use that to send to the server to impersonate the client. They do not have to know the info inside or decrypt it. If an attacker got that packet, saved it, they could send those exact bytes to the server when the server requests the client certificate. Im not sure how this encryption method protects from this type of attack. Then again, I am a total noob when it comes to socket-level encryption so I might be missing something big. Thanks!


Solution

  • Things are more complicated than that, and this picture has some flaws and mixes things between what is stored locally and what is exchanged.

    Have a look at https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake and specifically the "Client-authenticated TLS handshake" case.

    In summary:

    • at some point the server asks the client to send a certificate (this is not always needed so the server sends a specific message asking for it, CertificateRequest)
    • the client then replies with a Certificate message, containing its certificate
    • at that stage the server can already decide if it wants to go further or not based on the certificate presented; it is true at that stage that someone else could also send the same certificate, since it is public. But what follows explains why it would not work further inside the TLS handshake
    • after a ClientKeyExchange message from the server that contains various cryptographic data that will be used later to really encrypt the exchanges of application data,
    • the client sends a CertificateVerify message, which is a signature computed on TLS messages exchanges previously in the handshake, using the private key associated to the client certificate
    • the server receiving this can double-check that it is speaking with the true client because by attempting to verify the signature with the client public key (contained in the certificate) it will know if the remote party has indeed the proper associated private key or not.

    So an attacker cannot impersonate a client by just stealing the certificate (the same kind of protection exists in the other case, to authenticate the server), as long of course as the private key remains private. If the private key is stolen than all the above fails.

    There is no need at that point to understand all details of the cryptographic signature, just that the system is designed in such a way that everything encrypted by one of the key can only be decrypted by the other: if someone encrypts data with its private key, then anyone can decrypt it with its public key (which is, by definition, public; you then just have in general the problem of disseminating it, but not here as the public key is contained in the certificate which is exchanged just before in the handshake); this is off course useless for confidentiality (anyone can see what is encrypted) but is the basis of authentication since if the decryption works it means the sender had the associated private key to the public one you used to decrypt the thing.

    Note that with TLS 1.3 that just went out as a new standard, the number and nature of messages in the TLS exchange have changed slightly but the above cryptographic guarantee (of signing something with a private key so that the remote party can double-check with the associated public key) still holds.