It took me a while and finally found a working, but a bit ugly, solution. Not to bore you with the details, here are the step by step instruction on how to get HTTPS working on your development web server. Please note, this is not a good setup for live web servers, you will have to take security into account if you use this on a publicly available web server.
The first steps are taken from a web-archive from the Apple website (the page is no longer available) and I have altered the commands and paths so they fit nicely in a 10.6 or higher installation. The comments are 90% original Apple instructions.
Please note; This post is the second post in a series to build the “perfect” setup. See ‘The “Ultimate” Guide …’ or the menu on the right side for a complete list of related posts.
The first thing you need to do is generate the keys and certifications for the server. This requires using the Terminal. For sanity’s sake, create a directory (Folder) on the desktop called KeyGen and change into that directory.
mkdir ~/Desktop/KeyGen && cd ~/Desktop/KeyGen
You can now create an RSA private key and a CSR (Certificate Signing Request) for your server. An important part of private key cryptography is making sure that the parties involved in a transaction are who they say they are. This is accomplished through a third party — a trusted Certificate Authority (CA). The CA issues certificates that identify the parties, and confirms that the keys are correct and are cryptographically “signed.” Generating the CSR is the cryptographical equivalent to filling out a passport application. The CA will return the certificate (like a passport) which is used for identification and authentication.
You’re going to be self-signing the keys, so you’ll also be creating a CA key for the signature. The keys and certificates you create are purely for testing purposes. If you need to set up a production server, you should send your CSR to a proper CA, such as Verisign, for signing.
To create the RSA private key, issue the following command:
openssl genrsa -des3 -out server.key 2048
You will be asked for a passphrase (essentially a password for the key file) in the creation of this key. Do not forget this passphrase! You’ll have to do this all over if you forget the passphrase. You will need this passphrase later on in the process.
Now you’re ready to create a CSR (Certificate Signing Request), which is what you would normally send to a CA for signing. You’re going to sign it yourself.
You’ll be asked for some information when you start this. Most of it is pretty self explanatory, but one item, in particular, is not. Here’s what you’ll be asked for:
Country Name (2 letter code) [AU]: (enter your country code here)
State or Province Name (full name) [Some-State]: (Enter your state here)
Locality Name (eg, city) : (enter your city here)
Organization Name (eg, company) [Internet Widgits Pty Ltd]: (enter something here)
Organizational Unit Name (eg, section) : (enter something here)
Common Name (eg, YOUR name) : (this is the important one)
Email Address : (your e-mail address)
The entry for “Common Name” is the one that seems like it should be one thing, but is, in fact, another. For this entry, you want to enter your “Server Name” as it appears in your httpd.conf. As this is just a development environment, you can enter 127.0.0.1, which is the default IP for “localhost”. Now, keep in mind that using 127.0.0.1 is not the same as using “localhost”. The strings either match, or they don’t — Unix is like that.
openssl req -new -key server.key -out server.csr
You should now have two files; server.csr and server.key. Check this with
To sign the files, you will need a key for your CA (Certificate Authority). It’s just like your server.key – a Triple-DES encrypted, 2048 bit RSA key.
openssl genrsa -des3 -out ca.key 2048
Again, you’ll be asked for a passphrase, which, again, you should not forget.
Now you will create a self-signed CA Certificate using the RSA key you just made.
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
You’ll be asked for the passphrase for the key you just made, and, again, you’ll be asked to enter information about yourself. The main difference is that here, when you are asked for your “Common Name”, you want to enter your name — not the server name or IP address. This certificate is not associated with your server — it’s associated with you. It should look something like this:
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Texas
Locality Name (eg, city) :San Antonio
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bogus CA
Organizational Unit Name (eg, section) :Bogus CA for Dev
Common Name (eg, YOUR name) :Bob Davis
Email Address :email@example.com
Now you have 4 files in your directory — a CA key and certificate, and a server key and certificate signing request.
The next step is the important one. This is where you sign the server.key with your ca.crt. This will provide the security assurance that browsers need to establish a secure connection. It provides the identification and verification part of the public key encryption system where the keys themselves provide the mechanism for the encryption and decryption.
The easiest way to do this is to use the sign.sh script I have taken from the mod_ssl source.
## sign.sh -- Sign a SSL Certificate Request (CSR)
## written in 1998 by Ralf S. Engelschall
# argument line handling
if [ $# -ne 1 ]; then
echo "Usage: sign.sign <whatever>.csr"; exit 1
if [ ! -f $CSR ]; then
echo "CSR not found: $CSR"; exit 1
case $CSR in
*.csr ) CERT="`echo $CSR | sed -e 's/\.csr/.crt/'`" ;;
* ) CERT="$CSR.crt" ;;
# make sure environment exists
if [ ! -d ca.db.certs ]; then
if [ ! -f ca.db.serial ]; then
echo '01' >ca.db.serial
if [ ! -f ca.db.index ]; then
cp /dev/null ca.db.index
# create an own SSLeay config
cat >ca.config <<EOT
[ ca ]
default_ca = CA_own
[ CA_own ]
dir = .
certs = \$dir
new_certs_dir = \$dir/ca.db.certs
database = \$dir/ca.db.index
serial = \$dir/ca.db.serial
RANDFILE = \$dir/ca.db.rand
certificate = \$dir/ca.crt
private_key = \$dir/ca.key
default_days = 3650
default_crl_days = 30
default_md = md5
preserve = no
policy = policy_anything
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# sign the certificate
echo "CA signing: $CSR -> $CERT:"
openssl ca -config ca.config -out $CERT -infiles $CSR
echo "CA verifying: $CERT <-> CA cert"
openssl verify -CAfile ca.crt $CERT
# cleanup after SSLeay
rm -f ca.config
rm -f ca.db.serial.old
rm -f ca.db.index.old
# die gracefully
Save the script in ~/Desktop/KeyGen and execute;
sh sign.sh server.csr
You should get something like this, but with the information you entered for the server.csr:
CA signing: server.csr -> server.crt:
Using configuration from ca.config
Enter PEM pass phrase:
Check that the request matches the signature
The Subjects Distinguished Name is as follows
localityName :PRINTABLE:'San Antonio'
Certificate is to be certified until Sep 14 23:09:20 2002 GMT (365 days)
Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
CA verifying: server.crt <-> CA cert
Next step is to “install” the keys;
Make a directory in your /etc/apache2 called ssl.key
sudo mkdir /etc/apache2/ssl.key
Copy all of the contents of your working directory to the ssl.key directory you just made.
sudo cp -r * /etc/apache2/ssl.key/
One more step — and it’s another step that would not have a place in a production environment, but definitely makes life with your development system better: you’re going to remove the passphrase requirement from the server key by removing its encryption.
As things stand, when you start Apache, you will be prompted for a passphrase to read the private key. While this is fine for those who start and stop Apache manually from the command line every time, it does create some problems for those of us who have Apache (a.k.a. Web Sharing) start up automatically every time the system reboots. The system will hang on startup, patiently waiting for a passphrase that will never come — because there’s no way to enter the passphrase you’ve given the key! You’ll have to either boot into Mac OS 9 or boot into verbose mode to clear this problem if you forget.
Removing the pass phrase requirement is dangerous in a production environment, but acceptable for testing (especially if you enter information in your certificate request that makes it clear that this is a testing certificate, and not for production use).
Enter the following:
sudo cp server.key server.key.original
sudo openssl rsa -in server.key.original -out server.key
You’ll be asked for your sudo password and then for your key-passphrase. Comparing the two files server.key and server.key.original will show that they are now very different and that server.key.original contains a line stating, “Proc-Type: 4,ENCRYPTED”, that the decrypted file lacks.
The following steps are taken from the blog of Larry Ullman and adapted to service our needs.
In the /etc/apache2/httpd.conf file, find the line that says
LoadModule ssl_module libexec/apache2/mod_ssl.so
and make sure it does not have a # at the front of it. If it does, that means the line is commented-out, making that module inactive.
Go a little bit further down and remove the # from in front of:
That line includes the SSL configuration file. You can now save httpd.conf (you’ll likely need to enter the admin password at the prompt).
Next, edit the file httpd-ssl.conf, found in the /etc/apache2/extra folder. (By the way, /etc/apache2 and /private/etc/apache2 are two references to the same thing.) In the httpd-ssl.conf file, you need to edit two lines, indicating the location of the certficate and key. These two lines are a few lines apart.
The first is
and should be changed to
Then find this line
and change it to
That’s it there. Now save httpd-ssl.conf and close it (again, you’ll likely need to enter the admin’s password).
Now you can test how it worked. To do so, go to the Terminal and type:
sudo apachectl configtest
If it says Syntax OK, you’re good to go. If it gives an error, make a note of what it is and search the Web or post a question here.
If you got the Syntax OK message, you just need to restart Apache. In System Preferences > Sharing and uncheck and recheck Web Sharing.