Reputation: 12272
I was wondering why isn't there a simple way to find the ciphers supported by a particular ssl context? (Or did I miss it)
I know we can use socket.cipher()
to get the one being used for the connection for that particular socket
, but why not something to get all supported ciphers?
Another things is,
I have a server which is running openssl library with the cipher string "HIGH+TLSv1.2:!MD5:!SHA1"
. The client is a python file using the ssl
library, with default options, and after the connection is established the socket.cipher()
shows the below tuple
('DHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256)
How is the connection established with TLSv1, when I explicitly mentioned TLSv1.2, and how is it using SHA384
, when TLSv1 doesn't have support for anything higher then SHA1
?
Upvotes: 3
Views: 7438
Reputation: 13754
SSLContext.get_ciphers()
was added in Python 3.4.
Python 3.11.6 (main, Oct 2 2023, 13:45:54) [Clang 15.0.0 (clang-1500.0.40.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl
>>> from pprint import pprint
>>> pprint(ssl.create_default_context().get_ciphers()[0])
{'aead': True,
'alg_bits': 256,
'auth': 'auth-any',
'description': 'TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any '
'Enc=AESGCM(256) Mac=AEAD',
'digest': None,
'id': 50336514,
'kea': 'kx-any',
'name': 'TLS_AES_256_GCM_SHA384',
'protocol': 'TLSv1.3',
'strength_bits': 256,
'symmetric': 'aes-256-gcm'}
>>> pprint(sorted([cipher['name'] for cipher in ssl.create_default_context().get_ciphers()]))
['DHE-RSA-AES128-GCM-SHA256',
'DHE-RSA-AES128-SHA256',
'DHE-RSA-AES256-GCM-SHA384',
'DHE-RSA-AES256-SHA256',
'ECDHE-ECDSA-AES128-GCM-SHA256',
'ECDHE-ECDSA-AES128-SHA256',
'ECDHE-ECDSA-AES256-GCM-SHA384',
'ECDHE-ECDSA-AES256-SHA384',
'ECDHE-ECDSA-CHACHA20-POLY1305',
'ECDHE-RSA-AES128-GCM-SHA256',
'ECDHE-RSA-AES128-SHA256',
'ECDHE-RSA-AES256-GCM-SHA384',
'ECDHE-RSA-AES256-SHA384',
'ECDHE-RSA-CHACHA20-POLY1305',
'TLS_AES_128_GCM_SHA256',
'TLS_AES_256_GCM_SHA384',
'TLS_CHACHA20_POLY1305_SHA256']
>>>
Upvotes: 1
Reputation: 123541
I was wondering why isn't there a simple way to find the ciphers supported by a particular ssl context? (Or did I miss it)
Only OpenSSL 1.1.0 added a function SSL_CTX_get_ciphers to access this list and this functionality is not yet available in Python.
('DHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256)
How is the connection established with TLSv1, when I explicitly mentioned TLSv1.2, and how is it using SHA384, when TLSv1 doesn't have support for anything higher then SHA1?
According to the source code Python is using SSL_CIPHER_get_version to find out the version string. The matching OpenSSL documentation says for OpenSSL 1.0.2:
SSL_CIPHER_get_version() returns string which indicates the SSL/TLS protocol version that first defined the cipher. This is currently SSLv2 or TLSv1/SSLv3. In some cases it should possibly return "TLSv1.2" but does not; use SSL_CIPHER_description()
Thus it is a bug in OpenSSL which according to the documentation of the same function in OpenSSL 1.1.0 was fixed in the latest OpenSSL version.
Upvotes: 2