Hypertext Transfer Protocol

HTTPS is HTTP with encryption and verification.

HTTPS uses SSL/TLS to encrypt HTTP requests and responses between the client and server.

Popular tools such as OpenSSL and mkcert can encrypt and verify HTTP requests and responses.

There are two keys—a public key and a private key—and the public key is shared with client device via the SSL certificate of the server. Once a client connects to the server, both devices use the public and private key to agree on new keys (session keys) to encrypt any further communications between them:

  1. The public key is received by the client from the server and is used to encrypt the request for the TLS handshake
  2. The private key is used by the server to decrypt the request sent by the client. It is something only the server knows
  3. A third—shared—key, generated by both the client and server is used in open connections to encrypt and decrypt requests and responses

Possession of the private key by the server that matches the public key of a website’s SSL certificate proves that the server is the legitimate host for the website.

See https://www.cloudflare.com/learning/ssl/why-is-http-not-secure/ to read more about the process.

Encryption works like this:

  1. The client establishes a secure connection with a TLS handshake
  2. The server responds with its SSL/TLS configuration, public key, and a digital certificate from a trusted certificate authority such as Let’s Encrypt
  3. The client verifies the certificate (validity and expiration date) against the client’s trust store
  4. A shared session key is generated by the client and server
  5. Two messages are sent from the client and the server to confirm the session key encrypts correctly
  6. All further requests and responses are encrypted using the session key
  7. The session key is invalidated when the connection is severed after the client or the server closes the active connection

Example HTTP GET request:

GET /hello.txt HTTP/1.1
User-Agent: curl/7.63.0 libcurl/7.63.0 OpenSSL/1.1.l zlib/1.2.11
Host: www.example.com
Accept-Language: en

Example HTTPS GET request:

t8Fw6T8UV81pQfyhDkhebbz7+oiwldr1j2gHBB3L3RFTRsQCpaSnSBZ78Vme+DpDVJPvZdZUZHpzbbcqmSW1+3xXGsERHg9YDmpYk0VVDiRvw1H5miNieJeJ/FNUjgH0BmVRWII6+T4MnDwmCMZUI/orxP3HGwYCSIvyzS3MpmmSe4iaWKCOHQ==

Decoded from Base64:

p?WiAH^mhSFH{Y:CTeTdzsm*%|WXjXEU$oQ#bxSTeQX:><&T#+H-̦i{X

Example HTTP 200 OK response:

HTTP/1.1 200 OK
Date: Wed, 30 Jan 2019 12:14:39 GMT
Server: Apache
Last-Modified: Mon, 28 Jan 2019 11:17:01 GMT
Accept-Ranges: bytes
Content-Length: 12
Vary: Accept-Encoding
Content-Type: text/plain

Hello World!

The server sends its public key, domain name, and other identifying information to the certificate authority (CA) for verification. The CA verifies whether server is the owner of the domain with various checks and sends back a digital certificate that the server can use to prove domain-ownership to its clients.