3 minutes reading time
Before creating my self signed certificate, I create a folder to store everything and configuration file
Create a folder with:
Then create an openssl.cnf file to configure OpenSSL.
####################################
[ ca ]
default_ca = CA_default # Go to default CA section
[ CA_default ]
dir = /mnt/d/ggallCA # Where everything is kept
certificate = $dir/CA/cacert.pem # The CA certificate
database = $dir/CA/index.txt # The database
new_certs_dir = $dir/CA/certs # default place for new certs.
private_key = $dir/CA/privkey.pem # The CA private key
serial = $dir/CA/serial.txt # The current serial number for certificates
policy = policy_default
x509_extensions = certificate_extensions
# defaults for CA
default_days = 90 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = sha512 # use public key default MD
preserve = no # keep passed DN ordering
[ policy_default]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ certificate_extensions ]
basicConstraints = CA:false
####################################
[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_dn
x509_extensions = v3_ext
attributes = req_attributes
# extensions to add to certificate request
[ req_dn ]
countryName = Country Name (2 letter code)
countryName_default = US
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Iowa
localityName = Locality Name (eg, city)
localityName_default = Iowa CIty
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Greg Gallardo
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
emailAddress = greg@greggallardo.com
emailAddress_max = 64
# request attributes
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
[ v3_ext ]
basicConstraints = critical,CA:true
keyUsage = critical,digitalSignature, cRLSign, keyCertSign
[ v3_client ]
basicConstraints = CA:false
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
Now that a base directory and configuration file exist, the next thing we need is the CA certificates for signing our client and server certificates.
Create a new folder to store the CA certificate files.
Next we create the folders files specified in openssl.cnf
Run the following command to create the CA certificate and private key
-days means this one lasts a year
One your CA files exist you can use them to self-sign certificates.
Make a folder for your server certificates
Next use OpenSSL to make a signing request:
Then sign the request with your CA files.
If all went well OpenSSL will ask you if you want to sign the cert (just say yes) and commit (also say yes)
This will create new server certificate files. One in the CA/certs folder and one named serversert.pem in the server folder.
The server certificates are PEM files. You might need other formats. I often work with Microsoft Windows, so I sometimes need to convert PEM files to PKCS12 files. This can be done with OpenSSL.
When signing a request, you can use the -days flag to set the validity period of the request you're signing.
Then sign the request with your CA files.
Make a folder for your client certificates
Make client certificate signing requests with OpenSSL:
Then sign the client request with your CA files.
You will get copies of the certificate files in the CA/certs folder and clients folder
Adding -des3 to the command will add a password to the key.
Then sign the client request with your CA files.
If you want PKCS12 files, you can convert your PEM files with:
You can look at the contents of your certificates with openssl x509
For example, dumping the client lets me verify the dates and Subject fields I specified.
|
)
)
The following python script can be used to test out the server certificate
= # Replace with your own IP and Port values
=
# Set up the SSL context:
=
You can use --resolve with curl to test against the server.
adding -v to the command will give you more information
> curl
) )
))
))
))
))
))
))
))
))
)
> GET
> Host:
> User-Agent:
> Accept:
>
))
))
< HTTP/1.0
< Server:
< Date:
< Content-type:
<
))
If the common name for the certificate were wrong, you'd get a warning like this:
)
To test if the client certificate is valid, enable the ssl.CERT_REQUIRED option in the python server script
```
../
- ../ -in ..// - ..// - - -
cert_reqs=ssl.CERT_REQUIRED # Enable this to test client certificates
You can specify the client key and certificate with the `--key` and `--cert` options.
```bash
curl --cert ./client/clientcert.pem --key ./client/clientkey.pem --cacert ./CA/cacert.pem --resolve test.myfakeserver.local:8443:172.19.120.67 https://test.myfakeserver.local:8443
Hello world!