user7842128
user7842128

Reputation: 23

"ssl.SSLError: ... No shared cipher" when trying to handle HTTPS requests webserver

I'm trying to extend a web server I made to handle HTTPS requests via SSL. My prof said we should use ssl.wrap_socket and gave us the cipher to use.

Here is what I have so far:

from socket import *
import ssl

serverSocket = socket(AF_INET, SOCK_STREAM)
serverPort = 443
serverSocket.bind(("", serverPort))
serverSocket.listen(1)

while True:
    print ('Ready to serve...')
    connectionSocket, addr = serverSocket.accept()

    connectionSocket = ssl.wrap_socket(connectionSocket,
                                keyfile="./server.key",
                                certfile="./server.pem",
                                server_side=True,
                                cert_reqs=ssl.CERT_NONE,
                                ssl_version=ssl.PROTOCOL_SSLv23,
                                ca_certs=None,
                                do_handshake_on_connect=True,
                                suppress_ragged_eofs=True,
                                ciphers="AES128-SHA256")

    try:
        message =  (connectionSocket.recv(1024)).decode('utf-8')
        filename = message.split()[1]

        f = open(filename[1:],'rb')
        outputdata = f.read()
        f.close()

        connectionSocket.send(b'HTTP/1.1 200 OK\r\n\r\n')
        connectionSocket.send(outputdata)
        connectionSocket.send(b'\r\n')

        connectionSocket.shutdown(SHUT_RDWR)
        connectionSocket.close()

    except IOError:
        connectionSocket.send(b'HTTP/1.1 404 Not Found\r\n\r\n')
        connectionSocket.send(b'<html><head></head><body><h1>404 Not Found</h1></body></html>\r\n')

        connectionSocket.shutdown(SHUT_RDWR)
        connectionSocket.close()

serverSocket.close()

I've tested this in the command line with the following code and it seems to work. It shows me the right info about the SSL sessions such as protocol, cipher, session-ID, Master-key and the contents of index.html:

openssl s_client -connect localhost:443
GET /index.html

For the next section of the assignment I have to put "https://localhost:443/index.html" into my browser, but my webserver crashes with this error:

ssl.SSLError: [SSL: NO_SHARED_CIPHER] no shared cipher (_ssl.c:661)

What is wrong with my code?

Upvotes: 2

Views: 7441

Answers (1)

Steffen Ullrich
Steffen Ullrich

Reputation: 123531

                            ciphers="AES128-SHA256")

According to SSLLabs client tests AES128-SHA256 (called TLS_RSA_WITH_AES_128_CBC_SHA256 in the standards) is not supported by major browsers like Chrome or Firefox. Accepting only this single cipher on the server which is not supported by major clients makes that no common cipher can be found, i.e.

ssl.SSLError: [SSL: NO_SHARED_CIPHER] no shared cipher (_ssl.c:661)

The fix is to accept more ciphers on the server to include ciphers supported by the browser. See mozilla wiki for useful settings which can not only applied to major web servers but also your small server.

Upvotes: 1

Related Questions