Securing Connections with SSL/TLS
A few illustrated reminds about simple static http server.
For complete explanations, please have a look at : https://web.enib.fr/~harrouet
SSL/TLS encryption
For the moment we exchange messages without any security. Any bad people sniffing the connection can know exchanged messages between the client and the server.
The solution is encrypting messages. To encrypt and decrypt a dialog, we need a key.
If the key is the same for both sides, it’s a symetric encryption .
The encryption is represented by a locked box.
If both guys own the key already, the problem is over, they can exchange messages in a safe way.
Now we consider we have to transmit the key.
The client asked for connection to the server.
We consider a locked box with 2 locks : one to open, one to close.
As a result we need 2 different keys to encrypt and decrypt the message.
- The Server puts his message in the box
- The Server closes the box with his private key ( encryption )
- The Server sends the message with a public key
The private key belongs to the server, nobody else can get it.
The client receives a public key with the message.
- The Client opens the box with the public key
- The response is encrypted with the same public key
- The Client sends the message
- The Server is the only one who can open the box since he’s got the private key ( related to the public key ).
There is still a problem.
If a bad guy relays those messages, he will decode everything. This is the man in the middle attack.
The Client needs to know the server identity .
The identity card is a certificate given by a trusted certification authority.
- The Server sends a certification request and his public key to the certfication authority.
- A signed certificate is produced
- and encrypted by the certification authority private key.
- Now the server joins this encrypted certificate to his message
- encrypts the message
3 sends the message
- At reception,
- the client decrypts the certificate with a certification authority public key ( this key is present alread in updated web browsers ).
the client verifies this certificate is update and related to the public key. - then the client and the server can exchange messages to construct a new key.
This new key permits exchanging messages with symetric encryption, which is quicker than asymetric one.
Once done, both guys can exchange in a safe way.
Static / Dynamic Server ( with websocket support) with SSL/TLS support
Producing Keys and Certificate
We consider we are the certification authority. We will produce a self-signed certificate, which will trigger a web browser warning.
# AUTHORITY CERTIFICATION PRIVATE KEY
$ openssl genrsa -aes256 -out ca.key 2048
# AUTO SIGNED CERTIFICATE REQUEST FOR AUTHORITY CERTIFICATION
$ openssl req -new -x509 -days 3600 -key ca.key -out ca.crt -subj '/C=FR/ST=Bretagne/L=Brest/O=ENIB/OU=RX/CN=raspberrypi.local'
# SERVER KEYS GENERATION
$ openssl genrsa -aes256 -out serverKey.pem 2048
# SERVER CERTIFICATE REQUEST
$ openssl req -new -out serverCert.pem -key serverKey.pem -subj '/C=FR/ST=Bretagne/L=Brest/O=ENIB/OU=RX/CN=raspberrypi.local'
# CERTIFICATE CREATION AND ENCRYPTION
$ openssl x509 -req -in serverCert.pem -CA ca.crt -CAkey ca.key -CAcreateserial -out serverCert.pem -days 1800Static Server
Dynamic Server
httpDynServerWs.c
# RPI Terminal
./exec_httpDynServerWs 5555 8123
new HTTPS connection from 192.168.0.1:41324
Enter PEM pass phrase:
new HTTP connection from 192.168.0.1:57792
new HTTPS connection from 192.168.0.1:41326
new HTTPS connection from 192.168.0.1:41332
BUFFER == GET / HTTP/1.1
BUFFER == Host: 192.168.0.2:8123
BUFFER == Connection: keep-alive
BUFFER == Cache-Control: max-age=0
BUFFER == Upgrade-Insecure-Requests: 1
BUFFER == User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/71.0.3578.98 Chrome/71.0.3578.98 Safari/537.36
BUFFER == Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
BUFFER == Accept-Encoding: gzip, deflate, br
BUFFER == Accept-Language: en-US,en;q=0.9
BUFFER ==
new HTTPS connection from 192.168.0.1:41334
new HTTPS connection from 192.168.0.1:41336
BUFFER == GET /favicon.ico HTTP/1.1
BUFFER == Host: 192.168.0.2:8123
BUFFER == Connection: keep-alive
BUFFER == Pragma: no-cache
BUFFER == Cache-Control: no-cache
BUFFER == User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/71.0.3578.98 Chrome/71.0.3578.98 Safari/537.36
BUFFER == Accept: image/webp,image/apng,image/*,*/*;q=0.8
BUFFER == Referer: https://192.168.0.2:8123/
BUFFER == Accept-Encoding: gzip, deflate, br
BUFFER == Accept-Language: en-US,en;q=0.9
BUFFER ==
new HTTPS connection from 192.168.0.1:41340
new HTTPS connection from 192.168.0.1:41342
new HTTPS connection from 192.168.0.1:41344
BUFFER == GET /page.html HTTP/1.1
BUFFER == Host: 192.168.0.2:8123
BUFFER == Connection: keep-alive
BUFFER == Upgrade-Insecure-Requests: 1
BUFFER == User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/71.0.3578.98 Chrome/71.0.3578.98 Safari/537.36
BUFFER == Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
BUFFER == Referer: https://192.168.0.2:8123/
BUFFER == Accept-Encoding: gzip, deflate, br
BUFFER == Accept-Language: en-US,en;q=0.9
BUFFER ==