SSL uses Asymmetric Encryption like this :

  1. Server sends a copy of its asymmetric public key.
  2. Browser creates a symmetric session key and encrypts it with the server’s asymmetric public key.
  3. Server decrypts the asymmetric public key with its asymmetric private key to get the symmetric session key.
  4. Server and Browser now encrypt and decrypt all transmitted data with the symmetric session key.

But what happens if someone listens to this communication in "step 1", and does this:

  1. Listen to communication between server and client in step 1.
  2. When the server sends a copy of its asymmetric public key, hacker changes it to their own public key (that has its private key too) and sends it to client.
  3. Client create a session key and encrypts it with hacker's public key.
  4. Hacker listens to the line and gets the session key and decrypts it with its private key.

So he gets session key here. and then..

  1. Hacker encrypts the session key (that decrypted) by the last public key (that server sent)
  2. So the hacker has the session key now...

I used this algorithm in my project for communication between server and client. there is not any certification between them. is it right that I add some characters in public key and client checks them and makes it valid?

How we can fix it? any ideas?

  • @Xander I cant find the popular an appropriate answer in that question
    – Elahe
    Oct 2, 2014 at 5:37
  • Your first steps 2 and 3 are not correct. The session key is not generated by the client; is not encrypted; is not transmitted; and is not decrypted. It is calculated independently by both peers via a key agreement protocol.
    – user207421
    Mar 21, 2017 at 4:00

3 Answers 3


TLS is not broken, only your understanding of TLS ;)

The complete TLS is explained in this answer but to answer you concrete question:

  • The server does not send the public key simply to the client. The server sends a certificate (chain) to the client.
  • The client verifies the server certificates with one of the trusted certificates in its store.

So to use a MitM (Man in the Middle)-Attack as you described the attacker has to replace the server certificate (which is also possible but much more difficult).

A certificate is the public key signed by a CA (Certification Authority). So the client can check the servers certificat by verifying the signature on that cerificate.

All certificates have a chain of signed certificates up to a self signed certificate. This self signed certificate is called root certificate and is already included in your browser.

You can create your own CA by issuing a root certificate and use this to sign your own certificates. You then only have to import the created root certificate into the browsers certificate store. This is only feasible for small user bases or for companies with updates to the browsers.

  • And indeed a certificate is permanently attached to a certain domain name which the browser verifies as well, so the attacker can't send his own (legitimate) certificate which they obtained from a CA, unless they have control over the domain name.
    – ntoskrnl
    Oct 2, 2014 at 14:04

What you are missing is authentication, that is, confirming that the public key you recieved really was sent by the server.

In https for example, the Certificate Authority system is used. Certain organizations are chosen as ones we can trust. These organizations produce a public key that are then included in browsers. So, when you download firefox for example, a set of Trusted CA Certificates are included. Then, when connecting to a site via https, the browser checks whether the certificate given by the server is signed by one of the Trusted CA Certificates.

CAs then have the job of recieving requests for signing of certificates, and verifying that they are sent by the true owners of that site.

In a personal project, this means you need to include the public key of the server somewhere, to verify against the certificate you recieve.

  • Thanks for your answer. I need to include public key to the server somewhere? can u explain more? what should I do now?
    – Elahe
    Oct 2, 2014 at 5:55
  • @Elahe Sorry, I meant you need to store the public key to the server within the client, so that the client can check that the public keys (the one given and the one stored) are the same when connecting.
    – Shelvacu
    Oct 2, 2014 at 5:57
  • so u mean that client should access to server data base? and check the public keys with the stored one?! I dont want that client has direct access to my data base
    – Elahe
    Oct 2, 2014 at 6:02
  • @Elahe The client needs to have some other form of communication with the server that is not vulnerable to a man-in-the-middle attack. This could be something like manually writing down the SHA sum of the server key, and typing that into a text file that the client can read.
    – Shelvacu
    Oct 2, 2014 at 6:10
  • 1
    @Elahe: (For some reason, it won't let me log in to chat.) "how the client should know that its server public key" depends on the (imagined?) setting of the project. One approach is putting the server's public key into the client's software. Another approach is using a manual channel.
    – user49075
    Oct 2, 2014 at 7:53

This attack doesn't work because the client validates the server's certificate. If a man-in-the-middle (the hacker, in your scenario) replaces the server's public key with his own then the certificate won't validate, the client knows something is wrong, and aborts the transaction. The client will not use the wrong public key to encrypt the session key, so, this is not a threat.

  • thanks for your answer. actually I used this algorithm in my project for communication between server and clients. there is not any certification that check validation. how can I fix it, in my project? I should use certification? how?
    – Elahe
    Oct 2, 2014 at 5:43
  • @Elahe If you do not use certificates then you use TLS the wrong way.
    – Uwe Plonus
    Oct 2, 2014 at 5:48
  • How can I use certification in my project? I implement it myself
    – Elahe
    Oct 2, 2014 at 5:51
  • 3
    @Elahe I suggest that you check the documentation for the languages/libraries that you are using to implement your HTTPS connection.
    – Xander
    Oct 2, 2014 at 5:53

Not the answer you're looking for? Browse other questions tagged .