How to set ciphers in ssl python socket
Asked Answered
S

2

6

I want to create my own list of ciphersuites using the cipher strings. The following code works if I put only one string in the set_ciphers function. But I want a customized list of ciphers. There is other format like: ALL:!COMPLEMENTOFDEFAULT:!eNULL but this does not do the purpose I need. I have a customized list of different ciphers that I can not combine using the second format.

import socket, ssl
import pprint

context = ssl.create_default_context()

cipher = ['DHE-RSA-AES128-SHA', 'DHE-RSA-AES256-SHA', 'ECDHE-ECDSA-AES128-GCM-SHA256']
context.set_ciphers(cipher)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

domain = 'google.com'

sslSocket = context.wrap_socket(s, server_hostname = domain)

sslSocket.connect((domain, 443))
sslSocket.close()
print('closed')

The function set_ciphers can be found here.

Snailfish answered 11/4, 2018 at 11:49 Comment(0)
S
8

I could include more than one cipher simple by separating the ciphers with : and send all the ciphers as one string.

cipher = 'DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-GCM-SHA256'
context.set_ciphers(cipher)

This way, the client offers all the ciphers. You can make sure from this by calling context.get_ciphers() and you will see only the ciphers you inserted using set_cipher.

Snailfish answered 11/4, 2018 at 13:53 Comment(1)
hi, is the set_cipher should be called from client side or mandatory in both sides client and serverLeora
C
3

Even if ssl.SSLContext.get_ciphers returns the ciphers in a friendly format (a list of dictionaries), the other way around, things don't work quite the same.

According to [Python.Docs]: ssl - SSLContext.set_ciphers(ciphers):

Set the available ciphers for sockets created with this context. It should be a string in the OpenSSL cipher list format.

Following [OpenSSL]: CIPHER LIST FORMAT (emphasis is mine):

The cipher list consists of one or more cipher strings separated by colons. Commas or spaces are also acceptable separators but colons are normally used.

Therefore, strings like "DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-GCM-SHA256" should be used.
Translated to (your) code:

ciphers = ["DHE-RSA-AES128-SHA", "DHE-RSA-AES256-SHA", "ECDHE-ECDSA-AES128-GCM-SHA256"]
ciphers_str = ":".join(ciphers)  # "DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-GCM-SHA256"
context.set_ciphers(ciphers_str)
Consonance answered 26/5, 2018 at 0:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.