Skip to content

Instantly share code, notes, and snippets.

@drio
Last active July 28, 2022 15:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drio/920e08aee8aa0d2ff549e2c38b2beb22 to your computer and use it in GitHub Desktop.
Save drio/920e08aee8aa0d2ff549e2c38b2beb22 to your computer and use it in GitHub Desktop.
ssl_tls_concepts
*.cert
*.crt
*.key

Notes on SSL/TLS

Basics

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:

  1. Browser connects to server Using SSL (https)
  2. Server Responds with Server Certificate containing the public key of the web server.
  3. 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
  4. Browser uses this Public Key to agree a session key with the server.
  5. 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

Generating a cert with openssl

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.

In math we trust

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.

References

  1. https://gist.github.com/TopekoX/c37282a6563b7b2c889796013a479525
  2. https://stackoverflow.com/questions/10271197/how-to-extract-public-key-using-openssl
  3. https://stackoverflow.com/questions/10175812/how-to-generate-a-self-signed-ssl-certificate-using-openssl
  4. https://github.com/luizhlelis/go-lang-https-self-signed
  5. https://ubuntu.com/server/docs/security-trust-store
module drio/gist-test-golang-self-cert
go 1.18
package main
import (
"fmt"
"log"
"net/http"
"os"
)
func SecureServer(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("Secure Hello World.\n"))
}
func runServer() {
http.HandleFunc("/", SecureServer)
fmt.Println("Server, listening on :443")
err := http.ListenAndServeTLS(":443", "server.crt", "server.key", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
func main() {
if len(os.Args) == 2 && os.Args[1] == "client" {
fmt.Printf("Client")
os.Exit(0)
}
runServer()
}
.PHONY: self
self:
openssl req -x509 \
-newkey rsa:4096 \
-nodes \
-keyout server.key \
-out server.crt \
-sha256 \
-days 365 \
-subj '/C=US/ST=MA/L=Boston/O=Tufts/OU=DataTeam/CN=localhost'
# Extract public key
.PHONY: pub
pub:
openssl rsa -in server.key -pubout
clean:
rm -f *.crt *.key localhost.conf *.pem
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment