DEV Community

Cover image for Hands-On TLS: Inspect Certificates, Verify PFS, and Build a Local HTTPS Server
Spandan Sehgal
Spandan Sehgal

Posted on

Hands-On TLS: Inspect Certificates, Verify PFS, and Build a Local HTTPS Server

If you want to prove a site uses modern TLS (not guess), this tutorial gives you commands, a minimal Node.js HTTPS server, and a checklist you can run right now.


TL;DR

  • Run three quick checks:

    • Browser certificate
    • openssl s_client
    • DevTools mixed-content scan
  • Use the Node.js example to experiment locally

  • Look for:

    • TLS 1.2 / TLS 1.3
    • AEAD ciphers
    • ECDHE for Perfect Forward Secrecy (PFS)

1) Minimal HTTPS Server (Node.js)

Save this as server.js.
You’ll need key.pem and cert.pem (self-signed is fine for local testing).

// server.js
const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
};

https.createServer(options, (req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('secure chat placeholder\n');
}).listen(8443, () => {
  console.log('Listening on https://localhost:8443');
});
Enter fullscreen mode Exit fullscreen mode

Create a Local Certificate (Testing Only)

openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout key.pem \
  -out cert.pem \
  -days 365 \
  -subj "/C=IN/ST=State/L=City/O=Org/CN=localhost"
Enter fullscreen mode Exit fullscreen mode

Hit It

node server.js
curl -vkI https://localhost:8443 --insecure
Enter fullscreen mode Exit fullscreen mode

2) Inspect a Production Certificate (OpenSSL)

Command

openssl s_client -connect example.com:443 -servername example.com < /dev/null \
  | openssl x509 -noout -issuer -subject -dates -text
Enter fullscreen mode Exit fullscreen mode

What to Read

  • notBefore / notAfter — certificate validity window
  • Issuer — should be a known CA (Let’s Encrypt, DigiCert, etc.)
  • TLS protocol & cipher — TLS 1.3 preferred, AEAD ciphers ideal

3) Quick curl Sanity Check

curl -vI https://example.com
Enter fullscreen mode Exit fullscreen mode

Look for:

  • Successful SSL connection
  • Certificate verification
  • TLS handshake details in verbose output

4) Mixed Content Check (DevTools)

Chrome DevTools → Network → Reload → Filter http

Any http:// resource on an https:// page is mixed content.
Scripts loaded over HTTP are a real attack vector.


5) PFS & Cipher Notes

  • Check for ECDHE in the key exchange (automatic in TLS 1.3)
  • Prefer AEAD ciphers:

    • AES-GCM
    • ChaCha20-Poly1305

6) Session Resumption & 0-RTT (Short)

  • Session resumption (tickets) → faster reconnects
  • 0-RTT → lower latency, but replay-attack risk Use carefully for APIs and state-changing requests

7) Troubleshooting

  • If s_client fails:

    • Missing intermediate certs
    • Wrong CA bundle
    • SNI mismatch → use -servername
  • Corporate interception:

    • Cert issuer = corporate CA
    • Indicates MITM via proxy

8) Checklist (Copy–Paste)

  • Padlock present & certificate valid
  • openssl s_client → TLS 1.2/1.3 + AEAD
  • No mixed http:// resources
  • Server prefers ECDHE (PFS)
  • Certificate issued by a recognized CA (not self-signed)

Want the 60-second demo script and downloadable checklist?
I bundled the assets (plus a runnable GitHub gist) on Substack — grab them here:
👉 https://dub.sh/gFaM86e


Top comments (0)