Doing SSL client authentication is python

16,171

It seems that my problem was that I did not create the CA properly and wasn't signing keys the right way. A CA cert needs to be signed and if you pretend to be top level CA you self-sign your CA cert.

openssl req -new -newkey rsa:2048 -keyout ca.key -out ca.pem
openssl ca -create_serial -out cacert.pem -days 365 -keyfile ca.key -selfsign -infiles ca.pem

Then you use ca command to sign requests

openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl ca -out server.pem -infiles server.csr 
Share:
16,171
Mad Wombat
Author by

Mad Wombat

Updated on July 26, 2022

Comments

  • Mad Wombat
    Mad Wombat almost 2 years

    OK, I am trying to use client certificates to authenticate a python client to an Nginx server. Here is what I tried so far:

    Created a local CA

    openssl genrsa -des3 -out ca.key 4096
    openssl req -new -x509 -days 365 -key ca.key -out ca.crt
    

    Created server key and certificate

    openssl genrsa -des3 -out server.key 1024
    openssl rsa -in server.key -out server.key
    openssl req -new -key server.key -out server.csr
    openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
    

    Used similar procedure to create a client key and certificate

    openssl genrsa -des3 -out client.key 1024
    openssl rsa -in client.key -out client.key
    openssl req -new -key client.key -out client.csr
    openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
    

    Add these lines to my nginx config

    server {
        listen 443;
        ssl on;
        server_name dev.lightcloud.com;
        keepalive_timeout 70;
    
        access_log /usr/local/var/log/nginx/lightcloud.access.log;
        error_log /usr/local/var/log/nginx/lightcloud.error.log;
    
        ssl_certificate /Users/wombat/Lightcloud-Web/ssl/server.crt;
        ssl_certificate_key /Users/wombat/Lightcloud-Web/ssl/server.key;
        ssl_client_certificate /Users/wombat/Lightcloud-Web/ssl/ca.crt;
        ssl_verify_client on;
    
        location / {
            uwsgi_pass unix:///tmp/uwsgi.socket;
            include uwsgi_params;
        }
    }
    

    created a PEM client file

    cat client.crt client.key ca.crt > client.pem

    created a test python script

    import ssl
    import http.client
    
    context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    context.load_verify_locations("ca.crt")
    context.load_cert_chain("client.pem")
    
    conn = http.client.HTTPSConnection("localhost", context=context)
    conn.set_debuglevel(3)
    
    conn.putrequest('GET', '/')
    conn.endheaders()
    response = conn.getresponse()
    print(response.read())
    

    And now I get 400 The SSL certificate error from the server. What am I doing wrong?