======================================================= SSL: Creating a private CA ======================================================= :Title: SSL: Creating a private CA :Author: Douglas O'Leary :Description: SSL: Creating a private CA :Date created: 06/2007 :Date updated: 06/2009 :Disclaimer: Standard: Use the information that follows at your own risk. If you screw up a system, don't blame it on me... The steps below are outlined from the Network Security with OpenSSL book (ISBN: 0-596-00270-X) in chapter 3. It creates a CA that's not overly robust or user friendly but is certainly useable for small environments. If you want to create your own signed certificates or if you're doing an stunnel implementation for a client (guess where these steps came from?), than this will work. One note: be careful on step 3, generating the self signed cert for the CA authority. I ran that command exactly as it is in the openssl book. Their example shows the private key being written to a file. Even the one I ran here shows it going to stdout:: # openssl req -x509 -newkey rsa -out cacert.pem -outform PEM Generating a 2048 bit RSA private key .......................................................+++ ...........+++ writing new private key to stdout You can cut/paste that into the file identified as prvate_key in your openssl.conf file. I'm reasonably certain there's an arugment to write the key to a file, but I haven't looked for it yet. I ran into that little issue when I was troubleshooting key access to my CA and wanted to regenerate the keys 1. Create the CA environment: Identify and configure the root directory for the CA environment:: caroot=${abs_path_to_ca_root} cahost=${Host_that_will_be_used_as_CA} mkdir -p -m 755 ${caroot} mkdir -p -m 755 ${caroot}/certs mkdir -p -m 700 ${caroot}/private echo "01" > ${caroot}/serial.txt touch ${caroot}/index.txt 2. Create the CA openssl.conf file. NOTE: This file **should not** be the openssl default configuration file. This one makes some changs to the default environment. A full example config file can be found here Specific notes for the file generation follow: a. Sections are identified by square braces ([]). b. The first section identifies the default CA. Multiple CAs can be identified; however, I would imagine that would very quickly get more complicated than this CA could easily handle. c. The next section starts out by identifying where the keys are located. It then goes on to identify various parameters for the certificate revocation list (CRL) 1. default_crl_days identifies the number of days between CRLs 2. default_days identifies how long a certificate is valid. 3. default_md identifies the message digest algorithm used to sign the certificates. 4. policy_key names the section that will be used for the default policy. 5. x509_extensions: basically, this line prohibits any certs we create from being used to create other certs. There's a more detailed explanation in the book. d. The policy section: 1. Most of the entries in here say supplied. This means the information will be supplied on the command line. 2. optional entries are just that - not required by the CA. e. req section: 1. the command line used to request certs is pretty obvious. This section identifies information for that command. 2. distinguished_name identifies the name of the section that'll be used to supply most of the information for generating a self signed certficate (which is used to sign other certificates). Saves on typing later and keeps things consistent when you have to regenerate them. 3. basicConstraints: this one has to be CA:true because we're using the certificate to sign others. 3. Create the self-signed root certificate. Once done, move or copy cacert.pem to where you designated the key in the openssl.conf file. Alternatively, you could specify that file directly:: # export OPENSSL_CONF=${caroot}/openssl.conf # openssl req -x509 -newkey rsa -out cacert.pem -outform PEM Generating a 2048 bit RSA private key .......................................................+++ ...........+++ writing new private key to stdout NOTE: This is going to stdout! Enter PEM pass phrase: Enter passphrase here Verifying - Enter PEM pass phrase: Reenter passphrase here -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,FBE415D1818FE467 CYVxG9LrC83y/P6W+8W2VOFMruPAQBWrVb9CLnSV+FbBTpkAykv4B+kg4EdqSWb2 yXbIBaJ5lzRoNS+gjZBJvh20ylW+QQxKoTCjbhNRxwcVAzvkEnwFoMGTx5O4TEsF BPu1ZNgmuiX8G9N+Bpf94ggOQEAxcMLDxOpe8/4hBTcsUhmRU99iUY1hA59e+FBj rpbJMX6OMqcHYj4ikEyE9FitTxMgLrSyPTbk399CWiJy02Ymus7Vnc5ILw1o1RM+ vd1jNvKO/lC5MfcRCZoTqZq8/AXpJv/nKOKw47/R+4WrqF9d9a9Mx+Qd2s5/iIKa VWKNcsjwtvPgA0qFePcaTORFI7ssSQrv74cfMWQ7LhggnEo8yjpd0wpQZCQ4Sta5 N+DgrAUvyGmBuEFe6Ojqu8WHWVCvNR2CipyLayRnRHHpQCErAsuPJc0DdghWFZa5 9ORamSZSOCoPKYbOAFvwUKl3Ce9bEXvaT17LWGZR25qjLeFD9ejV8A5gycbkQEGa LXDsW+tWE7pZtPOFr4JTFm/ONeNGiH2cBY8P9GR+Nf8ivschvsm8ZjCX/gA4wtDu uhiCAPPoANo7FmUSo9O2AQ18uOzTE9bCdSoWNat+SwDrpVFLUS1h1ptu/zMDgSaE GOx5ESYue0ndY4c4EwmWnYUlnzwqLX3/YXFre7+N2krLVQVBO3xjVHgzd4MdlUPB qbSRI8BhAhDZTrL5Ws1fz8hGSGdcLIlyr6TQNDh9lcL9vfBAnXToJF0HdXNs6fqu d+fnkE3fa5fLH+zAdX4vbXIwJyP6ISna6k8WiEB+DJRbLZ6DpFiRoz/4xTzti/iQ KYh/uhiUl6NoutTxgOMFfQNr7OcO4lgUasG/3ifF+yNafU3uuxqLm8/Fj63TobR0 X3Z6lOX3eV+D6knR/7ag+3EqoZR2A3tdM7RFkRr/+qu669VGkuffT3qYOcArOq/r 9OqHG7MS62YgoHXT2g4zGMUvN3rKTREATHYjqTpjTfeiRzXN5basssFtw3SRY8Vr Do7MANxODOXDz6cwY0U/h/+WnCcoIEz+Z9sz2lV2RVVWfxB2PqoGgoGwun39OORb 9p+PgW5Q8+JvROq6h8chryEbYF0LP3MBR+jeKfXeRYu4O7rCFQBY7aMea0FDuqUC 3En0DwWrXK/ragKB4r0WMwkzbo9RICY38KOsHXRbH92hNKTAL5u2lZwn3srNkU/M omBSjh/+UW354eWrZLPZevBecuTFYHyuXZfu5Gpm5xVf+eG/FoRNIc+pP8STt49X gSTfm1r0iCdnhYModXnPzPbHK5aI4S+uEaH+rLIInf98+YpoZaZXOgOFDJaxQcj7 LYSWbbH1274WcTV7eFrhwWwRMgzbV17p4IAtc5kIAA/euUOMhvfxQOo+eiRLs6sU /E3vJp69oc4sSdItTLxaPIpY9E7psL7QZE4dU4xzc2bKTDFULrpq2uyr8niV8Wq4 pQIDRzm8b3C7G17OQv2OjjouguO6mwcTbpCVZKLuXqA9wqLwMJ1vN4T8E5wf1wYH zhl1W5TPInYaV307KwlOWM7ccQQzVeOCqIV/yQdY/L1wHSLp6UarCCKixzsFEYrx -----END RSA PRIVATE KEY----- ----- 4. Create a private key and a cert request. If you're doing these commands on the same system as the one you just generated the CA, execute ``unset OPENSSL_CONF`` a. Create a directory for the certificates. cd into it. :: mkdir -p -m 700 /root/certs; cd $_ b. Create a private key and cert request. Supply an aribitrary passphrase; we'll remove it later. Items in bold are what you enter:: openssl req -newkey rsa:1024 -keyout ${host}_private.pem -keyform PEM -out ${host}_req.pem Generating a 1024 bit RSA private key ....++++++ ....................................++++++ writing new private key to '${cahost}_private.pem' Enter PEM pass phrase: <==== Enter passphrase here Verifying - Enter PEM pass phrase: <=== Reenter same passphrase here ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:IL Locality Name (eg, city) []:Naperville Organization Name (eg, company) [Internet Widgits Pty Ltd]:Myco Organizational Unit Name (eg, section) []:IT Common Name (eg, YOUR name) []:FQDN of the host Email Address []:YOUR email address Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:Any arbitrary word; it's not used An optional company name []:Myco c. Send the request to the CA directory on ${cahost}:: scp ${host}_req.pem ${cahost}:${caroot} 5. Sign the certificate a. Log into ${cahost} as root, cd ${caroot} b. The CA needs specific items in the openssl.conf file. Since these entries aren't required for normal openssl operation, we need to use a different conf file:: export OPENSSL_CONF=${caroot}/openssl.conf Sign the request: openssl ca -in ${host}_req.pem Using configuration from ${caroot}/openssl.conf Enter pass phrase for ${caroot}/private/cakey.pem: Enter key passphrase from step #3 DEBUG[load_index]: unique_subject = "yes" Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'US' stateOrProvinceName :PRINTABLE:'IL' localityName :PRINTABLE:'Naperville' organizationName :PRINTABLE:'Myco' organizationalUnitName:PRINTABLE:'IT' commonName :PRINTABLE:'${cahost}.myco.com' emailAddress :IA5STRING:'oleary@myco.com' Certificate is to be certified until Jul 11 13:54:58 2009 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 Certificate: Data: Version: 3 (0x2) Serial Number: 3 (0x3) Signature Algorithm: md5WithRSAEncryption Issuer: CN=Myco, ST=IL, C=US/emailAddress=oleary@myco.com, O=Root Certificate Authority Validity Not Before: Jul 11 13:54:58 2008 GMT Not After : Jul 11 13:54:58 2009 GMT Subject: CN=${cahost}.myco.com, ST=IL, C=US/emailAddress=oleary@myco.com, O=Myco, OU=IT Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:c8:f2:4d:5b:a4:8d:c9:37:66:4f:77:3d:a4:b4: 2e:68:84:21:e5:64:37:56:ea:e5:f0:9c:72:f5:ba: 1c:65:21:9a:84:21:36:06:24:86:92:56:e6:f5:14: 30:d6:d9:6f:ad:8d:e9:11:b8:49:e1:3e:d7:f8:3d: 57:9b:64:29:87:9b:9c:c3:ea:00:80:b5:03:be:72: 02:dc:75:56:81:59:04:bb:e7:8e:53:56:16:0c:09: 97:a7:ea:0a:c7:e6:55:14:cb:92:1b:79:d6:1f:dc: 96:49:b7:ae:7a:d1:67:73:ff:6a:ef:69:e0:15:ef: 1b:67:b1:90:c2:2c:fe:96:c5 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Signature Algorithm: md5WithRSAEncryption 61:c7:0b:2e:e8:65:1b:d5:7b:b0:1a:60:4b:f0:07:b7:d6:b6: 9d:21:ea:b7:d5:3a:41:85:56:7f:ca:ed:ad:9d:06:d7:52:8c: 9e:13:2a:ef:0f:1f:32:a7:72:12:5d:e0:00:0e:ee:44:2f:ad: 83:06:c0:ce:94:b3:5e:5e:34:c9:eb:d1:bc:dc:bf:71:6c:e0: b5:65:0c:1d:64:60:e7:98:31:d4:93:18:7d:d7:4f:fc:e2:e6: 8e:e0:06:a2:1d:ff:db:41:d0:c4:ff:8e:18:7c:8e:b8:95:1d: d3:59:38:73:d1:92:c1:16:f5:91:8b:1e:a3:d6:cf:04:db:24: 84:34:28:c7:03:59:02:9c:ab:c4:31:06:dd:4b:8f:f0:64:09: e3:7a:13:e0:57:cf:a9:d8:81:7d:05:87:d9:a3:c4:78:03:36: fb:1e:58:65:a0:fd:ff:f4:8f:32:60:0a:dc:53:c8:4f:00:22: 43:d1:dd:7a:e6:a6:63:67:87:53:9a:7a:c5:be:f0:0c:92:74: f5:d2:05:c6:51:60:3b:b3:83:53:40:7e:dd:44:a5:c6:32:63: c6:99:c4:ea:c9:36:be:f5:e9:d3:98:27:eb:59:4b:52:4c:6f: d2:d6:4d:df:2e:22:7c:7e:18:7b:88:8a:5a:41:6a:53:e6:6b: 60:48:38:b8 -----BEGIN CERTIFICATE----- MIIC/TCCAeWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADB3MQwwCgYDVQQDEwNBTFUx CzAJBgNVBAgTAklMMQswCQYDVQQGEwJVUzEoMCYGCSqGSIb3DQEJARYZb2xlYXJ5 QGFsY2F0ZWwtbHVjZW50LmNvbTEjMCEGA1UEChMaUm9vdCBDZXJ0aWZpY2F0ZSBB dXRob3JpdHkwHhcNMDgwNzExMTM1NDU4WhcNMDkwNzExMTM1NDU4WjCBgTEgMB4G A1UEAxMXdXNpbGlnbjMubmRjLmx1Y2VudC5jb20xCzAJBgNVBAgTAklMMQswCQYD VQQGEwJVUzEoMCYGCSqGSIb3DQEJARYZb2xlYXJ5QGFsY2F0ZWwtbHVjZW50LmNv bTEMMAoGA1UEChMDQUxVMQswCQYDVQQLEwJJVDCBnzANBgkqhkiG9w0BAQEFAAOB jQAwgYkCgYEAyPJNW6SNyTdmT3c9pLQuaIQh5WQ3Vurl8Jxy9bocZSGahCE2BiSG klbm9RQw1tlvrY3pEbhJ4T7X+D1Xm2Qph5ucw+oAgLUDvnIC3HVWgVkEu+eOU1YW DAmXp+oKx+ZVFMuSG3nWH9yWSbeuetFnc/9q72ngFe8bZ7GQwiz+lsUCAwEAAaMN MAswCQYDVR0TBAIwADANBgkqhkiG9w0BAQQFAAOCAQEAYccLLuhlG9V7sBpgS/AH t9a2nSHqt9U6QYVWf8rtrZ0G11KMnhMq7w8fMqdyEl3gAA7uRC+tgwbAzpSzXl40 yevRvNy/cWzgtWUMHWRg55gx1JMYfddP/OLmjuAGoh3/20HQxP+OGHyOuJUd01k4 c9GSwRb1kYseo9bPBNskhDQoxwNZApyrxDEG3UuP8GQJ43oT4FfPqdiBfQWH2aPE eAM2+x5YZaD9//SPMmAK3FPITwAiQ9HdeuamY2eHU5p6xb7wDJJ09dIFxlFgO7OD U0B+3USlxjJjxpnE6sk2vvXp05gn61lLUkxv0tZN3y4ifH4Ye4iKWkFqU+ZrYEg4 uA== -----END CERTIFICATE----- Data Base Updated 6. The generic CA puts the newly signed certificates under the ${caroot}/certs directory with a numeric filename. The new key should be the last one modified. ID and copy the newly signed cert back to the target host:: ls -lart ${caroot}/certs | tail -1 scp ${caroot}/certs/##.pem ${host}:/root/certs/${host}_signed.pem 7. Remove the passphrase from the private key: Back on the target system, (not ${cahost}) run openssl command to remove the passphrase; update directories and filenames as appropriate:: openssl rsa -in ${host}_private.pem -out ${host}_np_private.pem Enter pass phrase for ${host}_private.pem: <== Enter passphrase used when creating the key writing RSA key mv ${host}_np_private.pem ${host}_private.pem