======================================================= Notes on openssl: ======================================================= :Title: Notes on openssl: :Author: Douglas O'Leary :Description: Notes on openssl: :Date created: 09/29/2015 :Date updated: 09/29/2015 :Disclaimer: Standard: Use the information that follows at your own risk. If you screw up a system, don't blame it on me... ~~~~~~~~~~~~~~~~~~~~ .. contents:: ~~~~~~~~~~~~~~~~~~~~ Overview: ========= Primarily notes on chapters 11 and 12 of the Bulletproof ssl and tls book from Ivan Ristic, isbn: 978-1907117046. I've skimmed through the majority of the chapters... The book is meticulously documented and referenced. Outstanding effort. My main goal, initially, was familiarization with good handle of the openssl chapters.. Now, we're there. Commands: ========= :command:`openssl version [-a]` Provides version information. Add the -a argument for more detail such as the OPENSSLDIR :command:`openssl help` Displays list of commands available. Help isn't actually a command. You'll get an error; however, it'll display the help text. :command:`openssl genrsa -aes128 -out ${key} 2048` Generates a 2048 bit RSA private key encrypted with AES128. Apparently, a reasonably good private key. A passphrase will be required. :command:`openssl rsa -in ${key} -out ${new_key}` Remove a passphrase from a private key. The line above requires that a passphrase be used. :command:`openssl rsa -text -in ${key}` Displays detailed information about the private key. :command:`openssl rsa -in ${key} -pubout [ -out ${outputfile} ]` Displays [ or stores ] the public key generated from the private key. :command:`openssl req -new -key ${key} -out fqdn.csr` Create a certificate signing request from a key. :command:`openssl req -text -in fqdn.csr -noout` Displays information about the cert signing request. Useful for validating correct information was entered. :command:`openssl x509 -text -in fqdn.crt -noout` Displays information about the certificate. :command:`openssl [x509|rsa] inform [PEM|DER] in ${key_in_proper_form} -outform [DER|PEM] -out ${key}` Converts between PEM and DER forms. rsa converts keys; x509 converts certs. :command:`openssl ciphers -v 'ALL:COMPLEMENTOFALL'` Results in 111 ciphers for version 1.0.1p and only 46 for 0.9.8e Installation: ============= Normally, you'll be using the OS installed version; however, for the practice and to follow the book (output snipped): :: yum -y install gcc wget http://www.openssl.org/source/openssl-1.0.1p.tar.gz tar -xzvf ./openssl-1.0.1p.tar.gz cd openssl-1.0.1p ./config --prefix=/opt/openssl --openssldir=/opt/openssl \ enable-ec_nistp_64_gcc_128 make depend make make install Openssl is also available via github: :: git clone https://github.com/openssl/openssl cd openssl ./config --prefix=/opt/openssl_git --openssldir=/opt/openssl_git \ enable-ec_nistp_64_gcc_128 make depend make make install As is my norm, I'm doing a bad thing and compiling as root. It's a kvm so I'm not overly worried. That being said, it's an incredibly bad idea and I really should stop it. I've compiled and installed both versions. The wget one is in /opt/openssl and will be the primary test bed.. the github version is installed at /opt/openssl_git. This results in three versions available: :: # openssl version # system version OpenSSL 1.0.1e-fips 11 Feb 2013 # /opt/openssl/bin/openssl version # wget version OpenSSL 1.0.1p 9 Jul 2015 # /opt/openssl_git/bin/openssl version # github version OpenSSL 1.1.0-dev xx XXX xxxx Trust Store: ============ When compiled on its own, openssl doesn't have a trust store. You can use the one the OS has or convert your own. Per the book, Mozilla maintains the best and most accurate one. The problem is that Mozilla uses a proprietary format. So, download a conversion utility and convert it: :: wget https://raw.github.com/bagder/curl/master/lib/mk-ca-bundle.pl # chmod 755 ./mk-ca-bundle.pl # ./mk-ca-bundle.pl Warning: Use of this script may pose some risk, -d risk for more details. SHA1 of old file: 0 Downloading 'certdata.txt' ... Get certdata over HTTPS with curl! % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1674k 100 1674k 0 0 749k 0 0:00:02 0:00:02 --:--:-- 969k SHA1 of new file: ed3c0bbfb7912bcc00cd2033b0cb85c98d10559c Processing 'certdata.txt' ... Done (155 CA certs processed, 48 skipped). The *risks* line was a bit frightening, so I checked: :: # ./mk-ca-bundle.pl -d risk Warning: Use of this script may pose some risk: 1) Using http is subject to man in the middle attack of certdata content 2) Default to 'release', but more recent updates may be found in other trees 3) certdata.txt file format may change, lag time to update this script 4) Generally unwise to blindly trust CAs without manual review & verification 5) Mozilla apps use additional security checks aren't represented in certdata 6) Use of this script will make a security engineer grind his teeth and swear at you. ;) The book doesn't go into what to do with the newly created ca-bundle.crt. Presumably, copy it into /opt/openssl/certs. Key and Certificate management: =============================== **This** is where I'll be hitting most often. Directly from the book: :: Most uses turn to openssl because they wish to configure and run a web server that supports SSL. 3 steps: 1. Generate a strong private key 2. Create a certificate signing request and send it to the CA. 3. Install the CA provided certificate in your web server. Key generation: --------------- Decisions to be made: Key algorithm: Web servers, pretty much only RSA. DSA is limited to 1024 (insecure) and ECDSA isn't widely supported yet. Key size: 2048 RSA keys. If using ECDSA, use 256 bits. Passphrase: Book suggests protecting your keys for systems other than web servers. Discussion involves availability considerations. Also mentions that private keys are cached in the clear in application memory so the security enhancement can be easily circumvented. Some examples: * Passphrase protected RSA key protected with AES: :: # openssl genrsa -aes128 -out fd.key 2048 Generating RSA private key, 2048 bit long modulus ..............+++ ...............................................................................................................................+++ e is 65537 (0x10001) Enter pass phrase for fd.key: <> Verifying - Enter pass phrase for fd.key: <> * AES-128 is the key encryption algorithm. * e value ``e is 65537 (0x10001)`` is the public exponent. Can use ``-3`` switch to further increase speed; but at an unacceptable security risk trade-off. * Display information on the private key: :: # openssl rsa -text -in ./fd.key | grep -v '^ ' Enter pass phrase for ./fd.key: <> Private-Key: (2048 bit) modulus: [[snip]] publicExponent: 65537 (0x10001) [[snip]] privateExponent: [[snip]] prime1: [[snip]] prime2: [[snip]] exponent1: [[snip]] exponent2: [[snip]] coefficient: [[snip]] -----BEGIN RSA PRIVATE KEY----- [[snip]] -----END RSA PRIVATE KEY----- * Generate the public key: :: # openssl rsa -in fd.key -pubout [ -out ${outputfile} ] Enter pass phrase for fd.key: writing RSA key -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApiudLn5TTWB8wg+T3aNt jfiwVMjEm/q7uXsIjsBl/dhcinV0H1jzRlfVva5wCSIkyGmrrN7P6AY7NJhsV9rz 2n92zf7IRxz27vmiIqAPtIENY1jg87QnC+J/GoHaZuiFyLKqRhX7HWVZkd28BYEW mLPuHlXCfXL9jBTzpMgg7eJ4U+2TQsZAShfzyKF5rj5u0B2uF0KVS/OxgRbmK2OS MJchJfhsSjZfF5waPEQNhoYLzxVh+o+ShtkjBXJAsVvKM8POfGipP3JzybvX1Pz+ 8r18x4a0NLKPmx+v2HVLhhCe09fYmIuYChDSgsAva1tzzCBQZ75bB9hpSh+blfMR FwIDAQAB -----END PUBLIC KEY----- * Examples of DSA and ECDSA keys are available in the book. CSR: ---- Notes: * Empty fields must be designated by a '.'; if you simply enter , the tool will use the default which may be defined in various ways. * Challenge password was originally intended for cert revocation. Don't enter anything. Creating the CSR: :: # openssl req -new -key fd.key -out fd.csr Enter pass phrase for fd.key: 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]:OCI Organizational Unit Name (eg, section) []:IT Common Name (e.g. server FQDN or YOUR name) []:caauth.olearycomputers.com Email Address []:dkoleary@olearycomputers.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Verify the information: :: # openssl req -text -in fd.csr -noout [[lotsa lines snipped]] Can also create a CSR from an existing signed cert. This means you're re-using the private key which is bad practice: :: # openssl x509 -x509toreq -in fd.crt -out fd.csr -signkey fd.key Can also create CSRs automatically. Script a config file that looks like: :: [req] prompt = no distinguished_name = dn req_extension = ext input_password = <> [dn] CN = caauth.olearycomputers.com emailAddress = dkoleary@olearycomputers.com O = OLeary Computers Inc L = Naperville C = US [ext] subjectAltName = DNS:caauth.olearycomputers.com,DNS:olearycomputers.com Note that you can't add extensions through the interactive process. Create the CSR w/o prompting via: :: # openssl req -new -config ./fd.conf -key fd.key -out fd.csr Adding extensions: ------------------ As noted, you can't add extensions such as alt names through the interactive process. To add extensions, create a text file with the extensions: :: # cat fd.ext subjectAltName = DNS:*.olearycomputers.com,DNS:olearycomputers.com The execute the certificate creation (demonstrated below) using the ``-extfile ${file}`` argument. Self-signed certs: ------------------ Two options: * Create a self-signed cert from the CSR we generated previously: :: # openssl x509 -req -days 365 -in fd.csr -signkey fd.key -out fd.crt Signature ok subject=/CN=caauth.olearycomputers.com/emailAddress=dkoleary@olearycomputers.com/O=OLeary Computers Inc/L=Naperville/C=US Getting Private key Enter pass phrase for fd.key: * Create self-signed cert from private key: :: # openssl req -new -x509 -days 365 -key fd.key -out fd1.crt The process will request the same information as provided above. NOTE that you can't interactively add alternate hostnames. * Create self-signed cert using the extensions file: :: # openssl x509 -req -days 365 -in fd.csr -signkey fd.key -out fd2.crt \ > -extfile fd.ext Signature ok subject=/CN=caauth.olearycomputers.com/emailAddress=dkoleary@olearycomputers.com/O=OLeary Computers Inc/L=Naperville/C=US Getting Private key Enter pass phrase for fd.key: Differences between self-signed and signed certs: ================================================= Need to be able to ID a cert that's self signed vs one that's CA signed. Private key types: ================== Types: ------ * Binary (DER) keys and certificates * ASCII (PEM) keys and certificate. base64-encoded DER key. * PKCS#7 cert: complext format for transport of signed/encrypted data. Extensions are usually .p7b or .p7c. Can include the entire cert chain. Java's keytool supports this format - implying we won't see it other than that? * PKCS#12 (PFX) keys and certs: stores and protects keys and, possibly, the entire cert chain. Seen wiht .p12 or .pfx extensions. Conversion: ----------- openssl [x509|rsa] inform [PEM|DER] in ${key_in_proper_form} -outform [DER|PEM] -out ${key} Converts between PEM and DER forms of certificates (not keys) Examples for converting between the other two forms are in the book. Cipher Suite selection: ======================= * To obtain a list of ciphers that openssl supports: :: # openssl ciphers -v 'ALL:COMPLEMENTOFALL' Results in 111 ciphers for version 1.0.1p and only 46 for 0.9.8e * Group keywords described in table 11.1; not duplicated here. Will need this when I initiate the battle for increased web security. Per book, the documentation available via openssl (binary/web) is out of date. * Keyword modifiers: Characters prepended to keywords that affect the ordering: +---+---------------------------------------------------+ | C | Action | +===+===================================================+ | | Append to the list. If already there, leave it | +---+---------------------------------------------------+ | - | Delete from list; can be reintroduced later. | +---+---------------------------------------------------+ | ! | Permanently delete; cannot be reintroduced later. | +---+---------------------------------------------------+ | + | Move to the end of the list | +---+---------------------------------------------------+ * Selecting cipher suites: Starting at loc 8064 and continuing through 8321 (this is a kindle book), book goes into some depth on how to select suites using keywords initially followed up by examples using suite names directly. * Benchmarking: Some useful guidelines: * Benchmark on the host that'll be doing the work * Benchmark a compiled updated version to get an idea of speed differential. Book's benchmarks suggest that openssl 1.0.1h is 2x faster than 0.9.8k * Add multiple cores to benchmarking via -multi switch * Add hardware acceleration, if available, via -evp switch. Private Certificate Authority: ============================== Features & limitations: ----------------------- * One root CA; subordinate CAs can be created. * Revocation info provided via CRLs and OCSP responders (maybe not) * subordinate CAs will be technicall constrained - only able to issue certs for specific hostnames