These are some notes on my basic research of tls, particularly in the context of webservices. I find myself forgetting some of this concepts so I thought I'd capture them here.
TLS are cryptographic protocols that run above tcp and below the application layer (see the OSI model).
We will talk only about TSL since it is a new version of SSL.
They provide:
- confidentiality (data is encrypted)
- integrity (no one can falsify the data flowing in a TLS flow)
- authentication (we can be sure that the person or system at the other end is who is suppose to be)
Encryption methods are symmetrical or asymmetrical. In S, we use the same cryptographic key to decrypt and encrypt the messages. AS methods use public and private keys. You encrypt your data with your private key and the public key of the recipient. The recipient uses your public key and her private key to decrypt the data. The recipient can also confirm that the sender was in fact the one that encrypted the data.
TLS uses a public and private key system for data encryption and data Integrity.
Public keys can be available to anyone, but, how do we know that a public key really belongs to the person or entity that it claims to be?
For that, we use a digital certificate.
A digital certificate provides a link between a public key and an entity. The link has been verified by a trusted third party, a certificate authority (CA) like letsencrypt.
To get a digital certificate you interact with the CA (challenges) and when the CA verifies that you are who you claim to be (or that you own a domain) they send you a public and private key enclosed in a certificate.
If someone wants your public key, you send the certificate. They verify the signature and then they can use your public key to establish an encrypted communication. They can trust your keys.
Here are the steps a browsers follows when talking tls against a webserver:
- Browser connects to server Using SSL (https)
- Server Responds with Server Certificate containing the public key of the web server.
- Browser verifies the certificate by checking the signature of the CA. To do this the CA certificate needs to be in the browser’s trusted store
- Browser uses this Public Key to agree a session key with the server.
- Web Browser and server encrypt data over the connection using the session key.
Common certificate file extensions:
- .DER
- .PEM (Privacy Enhanced Electron Mail)
- .CRT
- .CERT
To generate a self signed cert with openssl (see Makefile):
openssl req -x509 \
-newkey rsa:4096 \
-nodes \
-keyout key.pem \
-out cert.pem \
-sha256 \
-days 365 \
-subj '/C=US/ST=MA/L=Boston/O=Tufts/OU=DataTeam/CN=localhost'
The output is a public and private key (key.pem) and the self signed certificate (cert.pem).
If we write a TLS golang server (see main.go), we will get the following error when making a request to the server:
> curl https://localhost/
curl: (60) SSL certificate problem: self signed certificate
Of course we can bypass that with:
> curl -k https://localhost/
Secure Hello World.
But we don't want to do that. If we do so, we are exposed to a man-in-the-middle attack. We trust any encrypted data the server sends us.
We need to tell our OS that we trust ourselves as a CA.
For ubuntu systems, we can use the following process to trust a CA:
$ sudo apt-get install -y ca-certificates
$ sudo cp server.crt /usr/local/share/ca-certificates
$ sudo update-ca-certificates
after doing so we can then:
$ curl https://localhost:444/
Secure Hello World.
Fantastic.
- https://gist.github.com/TopekoX/c37282a6563b7b2c889796013a479525
- https://stackoverflow.com/questions/10271197/how-to-extract-public-key-using-openssl
- https://stackoverflow.com/questions/10175812/how-to-generate-a-self-signed-ssl-certificate-using-openssl
- https://github.com/luizhlelis/go-lang-https-self-signed
- https://ubuntu.com/server/docs/security-trust-store