A Simple SSL Client and Server in Python

Server

import socket
from socket import AF_INET, SOCK_STREAM, SO_REUSEADDR, SOL_SOCKET, SHUT_RDWR
import ssl

KEYFILE = 'server_key.pem'
CERTFILE = 'server_cert.pem'

def echo_client(s):
    while True:
        data = s.recv(8192)
        print(data.decode("utf-8"))
        if data == b'':
            break
        s.send(b'This is a response.')
        print('Connection closed')
    s.close()

def echo_server(address):
    s = socket.socket(AF_INET, SOCK_STREAM)
    s.bind(address)
    s.listen(1)
    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)

    s_ssl = ssl.wrap_socket(s, keyfile=KEYFILE, certfile=CERTFILE, server_side=True)

    while True:
        try:
            (c,a) = s_ssl.accept()
            print('Got connection', c, a)
            echo_client(c)
        except socket.error as e:
            print('Error: {0}'.format(e))

echo_server((socket.gethostbyname('localhost'), 8082))

Client

import ssl

port = 8082

import socket, ssl

while True:

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

    # Require a certificate from the server. We used a self-signed certificate
    # so here ca_certs must be the server certificate itself.
    ssl_sock = ssl.wrap_socket(s,cert_reqs=ssl.CERT_REQUIRED, ca_certs='server_cert.pem')

    ssl_sock.connect(('127.0.0.1', 8082))

    ssl_sock.write(str(input("Enter Something: ")).encode())

    ssl_sock.close()

4 thoughts on “A Simple SSL Client and Server in Python

  1. Reply

    Abhishek Deokar

    I need some help in a code where I’m trying to send some string to the server and convert it to upper case and send back to the client. I have applied AES encryption to the code to send and receive the data in encrypted format. On top of that I tried to apply SSL that was shown here.

    my server side code:
    import socket
    from socket import AF_INET, SOCK_STREAM, SO_REUSEADDR, SOL_SOCKET, SHUT_RDWR
    import hashlib
    from Crypto.Cipher import AES
    import ssl
    from ssl import PROTOCOL_TLS

    keyFile = “/home/maverick/Practice/Socket_Prog/key_cert/privateKey.pem”
    certFile = “/home/maverick/Practice/Socket_Prog/key_cert/sslCert.crt”

    KEY = hashlib.sha256(“some random password”).digest()

    IV = “abcdefghijklmnop”
    obj = AES.new(KEY, AES.MODE_CFB, IV)

    def echo_client(s):
    while True:
    data = s.recv(1024)
    if not data:
    break
    print “recieved from connection: “+str(data)
    data = str(data).upper()
    encrypted = obj.encrypt(data)
    print “encrypting…”
    print “encrypted data: “+str(encrypted)
    print “sending: “+str(data)
    s.send(encrypted)
    s.close()

    def main():
    host = “127.0.0.1”
    port = 5001

    s=socket.socket(AF_INET, SOCK_STREAM)
    s.bind((host,port))

    s.listen(1)
    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)

    s_ssl=ssl.wrap_socket(s, keyfile=keyFile, certfile=certFile, server_side=True,ssl_version=ssl.PROTOCOL_TLS)
    while True:
    try:
    c, addr = s_ssl.accept()
    print “connected with: “+str(addr)
    echo_client(c)
    except socket.error as e:
    print “Error:{0}”.format(e)

    if __name__ == “__main__”:
    main()

    my client side code:
    import socket
    import hashlib
    from Crypto.Cipher import AES
    import ssl

    KEY = hashlib.sha256(“some random password”).digest()

    IV = “abcdefghijklmnop”
    obj = AES.new(KEY, AES.MODE_CFB, IV)

    def main():
    host = “127.0.0.1”
    port = 5001

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    ssl_sock = ssl.wrap_socket(s, cert_reqs=ssl.CERT_REQUIRED, ca_certs=’/home/maverick/Practice/Socket_Prog/key_cert/sslCert.crt’)

    ssl_sock.connect((host,port))

    message = raw_input(“-> “)
    while message != ‘q’:
    s.send(message)
    data = s.recv(1024)
    print “received data: “+str(data)
    print “decrypting…”
    decrypted = obj.decrypt(data)
    print “received from server “+str(decrypted)
    message = raw_input(“-> “)

    s.close()

    if __name__ == “__main__”:
    main()

    I run them both in separate terminals and below is the trouble I run into
    server terminal:-
    python tcpServer.py
    connected with: (‘127.0.0.1’, 52456)
    Error:[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1858)

    client terminal:-
    python tcpClient.py
    -> hello
    received data: 3�|�&��W�˛У��C@|秬�(�
    decrypting…
    received from server S3�
    ��`?v���y����S��
    ת��voR~

  2. Reply

    Abhishek Deokar

    Nevermind the above comment… Figured it.

  3. Reply

    Kelvin Chai

    hi i got this error, may i know how to solve it?
    Traceback (most recent call last):
    File “server.py”, line 34, in
    echo_server((socket.gethostbyname(‘localhost’), 8082))
    File “server.py”, line 24, in echo_server
    s_ssl = ssl.wrap_socket(s, keyfile=KEYFILE, certfile=CERTFILE, server_side=True)
    File “C:\Python27\lib\ssl.py”, line 943, in wrap_socket
    ciphers=ciphers)
    File “C:\Python27\lib\ssl.py”, line 554, in __init__
    self._context.load_cert_chain(certfile, keyfile)
    IOError: [Errno 2] No such file or directory

    1. Reply

      grantcurell@gmail.com Post author

      It looks like you ran this with Python 2. It’s written in Python 3.

Leave a Reply