In this post I’ll show how to set up a simple HTTPS server with OpenSSL. I needed to learn this in order to research a problem regarding client certificate authentication on .NET. However, the instructions here contain some sub-steps that can be useful to know in other situations. The instructions are for Windows but, again, they may be useful on other platforms.
We’ll be using the openssl utility and ca.pl, supplied with the OpenSSL package. Before you begin, make sure the directory containing OpenSSL binaries is in the system path.
The openssl utility can already serve as a web server. We just need certificates for the server and for the client. We’ll begin by generating a sample Certificate Authority (CA). The certificates will be signed by this CA.
Generating the CA
To generate the CA, type
ca.pl -newca
You can press Enter to use the defaults for all fields except common name (type some identifier you’ll want to use for the CA) and password (must be at least 4 chars). You’ll be asked to enter a password three times; enter the same password at each time.
You now have a demo CA in the folder demoCA. Create an X509 .cer file that can be imported in the Windows trusted root certificates store:
openssl x509 -outform der < demoCA\cacert.pem > cacert.cer
Now import the certificate into the trusted root certificates store. Remember to remove the certificate from the store when you’re done, to reduce security risks.
Creating the server certificate
ca.pl -newreq
Use default values for everything except the common-name. For the common name, type the server name (e.g. http://www.example.com). Make sure that the name resolves to the local machine. You can simply use the local machine’s name, or add an appropriate entry to the hosts file.
ca.pl -sign
Type in the password for the CA key, and accept the certificate. Now you have the certificate in newcert.pem and the private key in newkey.pem. Make a unified PEM file for use with OpenSSL:
copy newcert.pem+newkey.pem server.pem
Creating a user certificate
The first two steps are more or less what the same as when you created the server certificate.
ca.pl -newreq
Use default values for everything except the common-name. For the common name, type a display name for the user. Sign the certificate:
ca.pl -sign
To be able to import the certificate and the associated private key into the Windows personal certificate store, we’ll need to create a pfx file. (The file is PKCS #12 format. Apparently, Firefox can also use this format.)
openssl pkcs12 -export -in newcert.pem -inkey newkey.pem > user.pfx
Import the certificate into the browser, and you’re ready for the big moment.
Running the server
openssl s_server -www -Verify 1 -CAfile demoCA\cacert.pem
You’ll need to enter the password for the server’s private key.
This will start a server on port 4433. Start up IE, and navigate to https://hostname:4433, where hostname is the name you typed earlier into the server certificate’s common name field. If everything was set up correctly, you’ll be prompted for a client certificate. After selecting the client certificate you’ll see a status page sent by OpenSSL.
Troubleshooting
On Windows, you may see an unable to write ‘random state’ error with every command.The commands work nonetheless. I believe it can be safely ignored in this context; it just means the private keys will be less than 100% random, which is OK for our purposes (but probably not for production use).
If you get a TXT_DB error number 2 error message when signing the certificate, it could mean that a certificate with the requested serial number is already registered in the CA database. You can edit the file demoCA/serial to change the next assigned serial number to something else.