Hello. Tell me please. For educational purposes, I am writing an SSL client. Read RFC 5246, 6101 It seems everything is clear written. That's just the problem. I tried to see how the connection goes in practice. Read the stream of bytes sent by the browser from the socket server. Then he wrote the exact same stream of bytes only with the host name yandex.ru. I connected to the host on port 443 and sent a stream of bytes. Also sent 32 random bytes to the server. In response, the server does not send anything, but simply closes the connection. I do not want to use third-party libraries. It is interesting to do everything yourself for a better understanding. I've been struggling with this for 2 weeks already. What am I doing wrong? How to even start a handshake?

  • Here I just tried to write a client on si. When I send randomly 32 bytes, the Bad Request response comes to the server. When I send a browser request, then everything hangs, and nothing happens - leprikon

2 answers 2

It will be easiest to practice with specific tools. Write SSL Dumps with Wireshark or Netmon . By dump, the dialogue between the server and the client becomes extremely transparent if you carefully study the rfc that guides you.

In addition, you just need another tool called OpenSSL . It includes a set of command line utilities that will help you quickly find the right direction when generating keys. Of course, you can generate them yourself, manually, without additional tools (although I do not understand why it is for you, but they will tell you about the advantages of using such tools, I will not even touch on this topic).

The next step is to spend some time on the certificate. If a server is available for you, for which you will know a certificate with a private key, you can decrypt all traffic (both server and client), Wireshark and Netmon can also do this. This server is now very easy to organize right at home, all you need is Apache . If you decrypt the traffic, it will be clear to you whether your implementation is working correctly, this self-test will save you a lot of time.

And now - the most interesting:

  1. The client sends a ClientHello , in which it sends a random 32 bytes to the server, a set of cipher and a set of compression methods that it can handle.
  2. The server responds with ServerHello , in which it sends its random 32 bytes to the client, the cipher and compression method that it chooses from those offered by the client. Then, the server sends a set of certificates (usually one) with a public key and a terminating empty message to the DONE ("everything is fine, I am ready for the handshake").
  3. The following message, the client sends to the server the pre master secret encrypted with the public key. It can only be decrypted with the server's private key, which, in essence, guarantees the security of the dialogue. Next, the client sends the ChangeCipherSpec packet ("everything is fine, we start communicating with the current security settings"). The client's last message is the Finished package, in which he encrypted a 12-byte verification hash. Already encrypted with a key that must be generated from the pre master secret .
  4. In response, the server sends 2 messages in succession: the same as ChangeCipherSpec and its own Finished .

At this, hendseyk completed. Now about the keys. A pre master secret generated from the pre master secret master secret . A key expansion sequence is generated from the master secret , which is the donor for the main keys that are used to encode and hash traffic. The length and availability of the corresponding keys is determined by the selected cipher. In all SSL-RFC in the application there are labels by which these parameters can be determined. There is even an example on which a specific cipher is parsed.

This is the main algorithm. In detail, there are already specific implementations of the protocols, for example: the SSL3.0 and SSL3.1 (TLS1.0) generation algorithms are different, they are described in the corresponding RFCs.

  • Thank you so much for such a detailed and detailed answer. Now everything became extremely clear to me. I will do just that as you said. Thanks again very much) - leprikon
  • Please glad to help). The topic is actually not simple in the sense that there are so many different nuances, and it is very easy to make a mistake. I hope you have the patience to finish the job. - mega

Read the stream of bytes sent by the browser from the socket server. Then he wrote exactly the same stream of bytes, only with the host name yandex.ru .

The server breaks the connection because the handshake procedure is broken.

  1. The client and server agree on the use of a symmetric session key . This key is re-created for each new session based on a key pair of parties and additional randomly selected parameters. Therefore, the server refused to accept the key used in the captured communication session completely unknown to him, and broke the connection.
  2. 32 random bytes were sent before the completion of the handshake, but because the server took them for the correct beginning of the client's response and did not answer, waiting for the transfer to continue.
  • Thank you very much for your response. Could you please clarify the sequence of establishing the connection, because for some reason I thought that client hello (in my understanding, this is a system date + 28 random bytes or 32 random bytes) is the beginning. It seems that I imagined everything quite wrong - leprikon