How to Check Negotiated Cipher Suite in Python

Connect to a TLS server with Python's ssl module and print the negotiated protocol version and cipher suite details.

Easy Python 3.9+ Aug 9, 2026 Auth & security at scale 17 views 0 copies

Python code

19 lines
Python 3.9+
import ssl
import socket

def get_cipher_suites(hostname, port=443):
    context = ssl.create_default_context()
    context.set_ciphers("DEFAULT:@SECLEVEL=2")
    
    with socket.create_connection((hostname, port), timeout=5) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as ssock:
            cipher = ssock.cipher()
            version = ssock.version()
            return version, cipher

if __name__ == "__main__":
    version, cipher = get_cipher_suites("www.google.com")
    print(f"TLS Version: {version}")
    print(f"Negotiated Cipher: {cipher[0]}")
    print(f"Protocol: {cipher[1]}")
    print(f"Key Exchange Bits: {cipher[2]}")

Output

stdout
TLS Version: TLSv1.3
Negotiated Cipher: TLS_AES_256_GCM_SHA384
Protocol: TLSv1.3
Key Exchange Bits: 256

How it works

The ssl.create_default_context() builds a context with secure defaults, including system CA certificates. Calling set_ciphers with DEFAULT:@SECLEVEL=2 ensures only ciphers meeting OpenSSL's security level 2 (112-bit or stronger) are permitted. After wrapping the socket with the TLS context, ssock.cipher() returns a tuple with the cipher name, protocol version, and key exchange bits. ssock.version() gives the TLS protocol version that was actually negotiated. This approach works without extra dependencies, making it easy to audit remote endpoints for weak cipher support.

Common mistakes

  • Forgetting the server_hostname argument, which disables SNI and may cause handshake failures.
  • Using `ssl.wrap_socket` (deprecated) instead of `context.wrap_socket`.
  • Not catching socket.timeout, which can crash the script on unresponsive hosts.
  • Assuming the key exchange bits reflect symmetric key strength; they represent the ephemeral key size.

Variations

  1. Use `cryptography` library’s `ssl` integration to get more detailed cipher info.
  2. Connect to a local test server with a custom SSL context for controlled testing.

Real-world use cases

  • Auditing a server’s TLS configuration during security compliance checks.
  • Automatically verifying that endpoints use strong ciphers before enabling client connections.
  • Debugging handshake failures caused by unsupported or weak cipher suites on legacy systems.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Auth & security at scale

Related tutorials and quizzes for this topic.