tls_demo.py

Download
python 313 lines 9.9 KB
  1"""
  2TLS and Certificate Demo
  3=========================
  4
  5Educational demonstration of TLS/SSL concepts:
  6- Certificate parsing from a live server
  7- TLS connection information display
  8- Self-signed certificate generation commands
  9- Certificate chain verification concepts
 10
 11Uses only Python standard library (ssl, socket).
 12No external dependencies required.
 13
 14Note: Requires internet connection for live server examples.
 15"""
 16
 17import ssl
 18import socket
 19import datetime
 20import textwrap
 21import hashlib
 22
 23print("=" * 65)
 24print("  TLS and Certificate Demo")
 25print("=" * 65)
 26print()
 27
 28
 29# ============================================================
 30# Section 1: TLS Connection to a Live Server
 31# ============================================================
 32
 33print("-" * 65)
 34print("  Section 1: TLS Connection Information")
 35print("-" * 65)
 36
 37hostname = "www.google.com"
 38port = 443
 39
 40print(f"\n  Connecting to {hostname}:{port}...")
 41print()
 42
 43try:
 44    context = ssl.create_default_context()
 45
 46    with socket.create_connection((hostname, port), timeout=5) as sock:
 47        with context.wrap_socket(sock, server_hostname=hostname) as tls_sock:
 48            # Connection info
 49            print(f"  TLS Version:     {tls_sock.version()}")
 50            print(f"  Cipher Suite:    {tls_sock.cipher()[0]}")
 51            print(f"  Cipher Bits:     {tls_sock.cipher()[2]}")
 52            print()
 53
 54            # Certificate info
 55            cert = tls_sock.getpeercert()
 56
 57            # Subject
 58            subject = dict(x[0] for x in cert.get("subject", ()))
 59            print(f"  Subject:")
 60            for key, value in subject.items():
 61                print(f"    {key}: {value}")
 62
 63            # Issuer
 64            issuer = dict(x[0] for x in cert.get("issuer", ()))
 65            print(f"\n  Issuer:")
 66            for key, value in issuer.items():
 67                print(f"    {key}: {value}")
 68
 69            # Validity period
 70            not_before = cert.get("notBefore", "N/A")
 71            not_after = cert.get("notAfter", "N/A")
 72            print(f"\n  Valid From:      {not_before}")
 73            print(f"  Valid Until:     {not_after}")
 74
 75            # Serial number
 76            serial = cert.get("serialNumber", "N/A")
 77            print(f"  Serial Number:   {serial}")
 78
 79            # Subject Alternative Names
 80            sans = cert.get("subjectAltName", ())
 81            if sans:
 82                san_list = [v for _, v in sans[:5]]
 83                print(f"\n  Subject Alt Names ({len(sans)} total):")
 84                for san in san_list:
 85                    print(f"    - {san}")
 86                if len(sans) > 5:
 87                    print(f"    ... and {len(sans) - 5} more")
 88
 89            # DER-encoded certificate for fingerprint
 90            der_cert = tls_sock.getpeercert(binary_form=True)
 91            sha256_fp = hashlib.sha256(der_cert).hexdigest()
 92            sha1_fp = hashlib.sha1(der_cert).hexdigest()
 93            print(f"\n  SHA-256 Fingerprint:")
 94            print(f"    {':'.join(sha256_fp[i:i+2] for i in range(0, 32, 2))}...")
 95            print(f"  SHA-1 Fingerprint:")
 96            print(f"    {':'.join(sha1_fp[i:i+2] for i in range(0, len(sha1_fp), 2))}")
 97
 98except socket.timeout:
 99    print("  Connection timed out. Skipping live server demo.")
100except Exception as e:
101    print(f"  Connection failed: {e}")
102    print("  (This section requires internet access)")
103
104print()
105
106
107# ============================================================
108# Section 2: TLS Protocol Details
109# ============================================================
110
111print("-" * 65)
112print("  Section 2: TLS Protocol & Supported Configurations")
113print("-" * 65)
114
115print(f"""
116  Python SSL module information:
117  - OpenSSL version:    {ssl.OPENSSL_VERSION}
118  - Default protocol:   TLS (auto-negotiated)
119""")
120
121# Show supported protocols
122ctx = ssl.create_default_context()
123print(f"  Default context settings:")
124print(f"    Protocol:         TLSv1.2+ (minimum)")
125print(f"    Verify mode:      {ctx.verify_mode.name}")
126print(f"    Check hostname:   {ctx.check_hostname}")
127print()
128
129# Demonstrate cipher suite listing
130print("  Enabled cipher suites (top 10):")
131ciphers = ctx.get_ciphers()
132for i, c in enumerate(ciphers[:10]):
133    protocol = c.get("protocol", "?")
134    name = c.get("name", "?")
135    bits = c.get("alg_bits", 0)
136    print(f"    {i+1:2}. [{protocol}] {name} ({bits}-bit)")
137if len(ciphers) > 10:
138    print(f"    ... and {len(ciphers) - 10} more")
139print()
140
141
142# ============================================================
143# Section 3: Certificate Chain Concepts
144# ============================================================
145
146print("-" * 65)
147print("  Section 3: Certificate Chain of Trust")
148print("-" * 65)
149
150print("""
151  Certificate Chain Structure:
152  ============================
153
154  +---------------------------+
155  |    Root CA Certificate    |  Self-signed, pre-installed
156  |  (e.g., DigiCert Root)   |  in OS/browser trust store
157  +---------------------------+
158              |
159              | signs
160              v
161  +---------------------------+
162  | Intermediate CA Cert      |  Signed by Root CA
163  | (e.g., DigiCert G2)      |  Provides operational isolation
164  +---------------------------+
165              |
166              | signs
167              v
168  +---------------------------+
169  | Server Certificate        |  Signed by Intermediate CA
170  | (e.g., *.google.com)     |  Presented during TLS handshake
171  +---------------------------+
172
173  Verification Process:
174  1. Server sends its certificate + intermediate cert(s)
175  2. Client finds the issuer of each cert in the chain
176  3. Client verifies each signature using issuer's public key
177  4. Chain must end at a trusted Root CA in the trust store
178  5. Client checks: expiration, revocation (CRL/OCSP), hostname
179""")
180
181# Show trusted CA count
182default_certs = ssl.create_default_context()
183ca_certs = default_certs.get_ca_certs()
184print(f"  Trusted Root CAs in system store: {len(ca_certs)}")
185if ca_certs:
186    print(f"\n  Sample trusted CAs:")
187    seen = set()
188    count = 0
189    for ca in ca_certs:
190        org = dict(x[0] for x in ca.get("issuer", ())).get(
191            "organizationName", "Unknown"
192        )
193        if org not in seen:
194            seen.add(org)
195            print(f"    - {org}")
196            count += 1
197            if count >= 8:
198                break
199    print(f"    ... and more")
200print()
201
202
203# ============================================================
204# Section 4: Self-Signed Certificate Commands
205# ============================================================
206
207print("-" * 65)
208print("  Section 4: Self-Signed Certificate Generation (OpenSSL)")
209print("-" * 65)
210
211print("""
212  The following OpenSSL commands create certificates for
213  development/testing. NOT for production use.
214
215  --- Generate Private Key ---
216  $ openssl genrsa -out server.key 2048
217
218  --- Generate Self-Signed Certificate (valid 365 days) ---
219  $ openssl req -new -x509 -key server.key -out server.crt \\
220      -days 365 -subj "/CN=localhost/O=Dev/C=US"
221
222  --- Generate with Subject Alternative Names ---
223  $ openssl req -new -x509 -key server.key -out server.crt \\
224      -days 365 -subj "/CN=localhost" \\
225      -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
226
227  --- View Certificate Details ---
228  $ openssl x509 -in server.crt -text -noout
229
230  --- Verify Certificate Chain ---
231  $ openssl verify -CAfile ca.crt server.crt
232
233  --- Test TLS Connection ---
234  $ openssl s_client -connect example.com:443 -servername example.com
235
236  --- Generate Let's Encrypt Certificate (production) ---
237  $ certbot certonly --standalone -d yourdomain.com
238
239  Note: For Python development servers:
240    context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
241    context.load_cert_chain('server.crt', 'server.key')
242""")
243
244
245# ============================================================
246# Section 5: TLS Handshake Visualization
247# ============================================================
248
249print("-" * 65)
250print("  Section 5: TLS 1.3 Handshake Overview")
251print("-" * 65)
252
253print("""
254  TLS 1.3 Handshake (1-RTT):
255  ===========================
256
257  Client                              Server
258    |                                    |
259    |  ClientHello                       |
260    |  + supported_versions (TLS 1.3)   |
261    |  + key_share (X25519/P-256)       |
262    |  + signature_algorithms            |
263    |  + cipher_suites                   |
264    | ---------------------------------> |
265    |                                    |
266    |                    ServerHello     |
267    |              + selected version    |
268    |              + selected key_share  |
269    |              {EncryptedExtensions} |
270    |              {Certificate}         |
271    |              {CertificateVerify}   |
272    |              {Finished}            |
273    | <--------------------------------- |
274    |                                    |
275    |  {Finished}                        |
276    | ---------------------------------> |
277    |                                    |
278    |  [Application Data] <============> |
279    |  (encrypted with derived keys)     |
280
281  Key improvements in TLS 1.3:
282  - 1-RTT handshake (was 2-RTT in TLS 1.2)
283  - 0-RTT resumption (with replay protection caveats)
284  - Removed insecure algorithms (RC4, 3DES, SHA-1, RSA key transport)
285  - Forward secrecy mandatory (ephemeral DH only)
286  - Simplified cipher suites (only 5 defined)
287""")
288
289
290# ============================================================
291# Section 6: Summary
292# ============================================================
293
294print("=" * 65)
295print("  Summary")
296print("=" * 65)
297print("""
298  TLS Best Practices:
299  - Minimum TLS 1.2, prefer TLS 1.3
300  - Use strong cipher suites (AES-GCM, ChaCha20-Poly1305)
301  - Enable HSTS (HTTP Strict Transport Security)
302  - Use certificate pinning for mobile apps
303  - Monitor certificate expiration
304  - Use Let's Encrypt for free production certificates
305  - Never disable certificate verification in production
306    (ssl._create_unverified_context is for testing ONLY)
307
308  Common SSL/TLS Errors:
309  - CERTIFICATE_VERIFY_FAILED: CA not trusted or expired
310  - HOSTNAME_MISMATCH: cert CN/SAN doesn't match hostname
311  - TLSV1_ALERT_PROTOCOL_VERSION: server requires newer TLS
312""")