Real-World
Uses for OpenSSL
Ryan Matteson
OpenSSL is an open source toolkit that implements the protocols
and algorithms required by the SSL (Secure Socket Layer) and TLS
(Transport Layer Security) protocols. The toolkit includes a general-purpose
cryptographic API, a full-featured command-line utility, and uses
an Apache-style license. In this article, I will introduce the OpenSSL
command-line utility and provide several examples of how OpenSSL
can be used to secure data and manage digital certificates. Two
example shell scripts are included to illustrate how OpenSSL can
be used to monitor secure Web servers and provide notification when
digital certificates are about to expire.
Acquiring and Installing OpenSSL
The source code for OpenSSL can be acquired from the main OpenSSL
Web site at:
http://www.openssl.org/source
or through one of the numerous mirrors. To install OpenSSL from source
code, the latest tar archive should be downloaded, uncompressed, and
extracted:
$ gunzip openssl-X.X.X.tar.gz
$ tar xfv openssl-X.X.X.tar
$ cd openssl-X.X.X
Once the source code has been extracted, review the INSTALL file.
The INSTALL file contains detailed information on compiling OpenSSL
and describes the flags available to the build process. To build OpenSSL
with the default options, the config and make commands
can be executed:
$ ./config
$ make
$ make install
The config command will invoke the Configure script, which
is written in Perl. To avoid any issues with the configuration process,
double-check that Perl 5.X or higher is installed. Once the build
process is complete, the libraries and executables will be available
in /usr/local/ssl. To change the default installation location, the
"--prefix" option can be passed to the config script:
$ ./config --prefix /opt/openssl
Using OpenSSL
Once OpenSSL is installed, the command-line interface can be accessed
with the openssl command:
$ openssl help
openssl:Error: 'help' is an invalid command.
Standard commands
asn1parse ca ciphers crl crl2pkcs7
dgst dh dhparam dsa dsaparam
enc engine errstr gendh gendsa
genrsa nseq ocsp passwd pkcs12
pkcs7 pkcs8 rand req rsa
rsautl s_client s_server s_time sess_id
smime speed spkac verify version
x509
Message Digest commands (see the 'dgst' command for more details)
md2 md4 md5 mdc2 rmd160
sha sha1
Cipher commands (see the 'enc' command for more details)
aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb aes-256-cbc
aes-256-ecb base64 bf bf-cbc bf-cfb
bf-ecb bf-ofb cast cast-cbc cast5-cbc
cast5-cfb cast5-ecb cast5-ofb des des-cbc
des-cfb des-ecb des-ede des-ede-cbc des-ede-cfb
des-ede-ofb des-ede3 des-ede3-cbc des-ede3-cfb des-ede3-ofb
des-ofb des3 desx idea idea-cbc
idea-cfb idea-ecb idea-ofb rc2 rc2-40-cbc
rc2-64-cbc rc2-cbc rc2-cfb rc2-ecb rc2-ofb
rc4 rc4-40 rc5 rc5-cbc rc5-cfb
rc5-ecb rc5-ofb
The help command is not recognized by OpenSSL, so all available
menu options are printed. The individual help screens (Standard Commands,
Message Digests, and Cipher commands) can be accessed individually
with the list-standard-commands, list-message-digest-commands,
and list-cipher-commands options:
$ openssl list-standard-commands
$ openssl list-message-digest-commands
$ openssl list-cipher-commands
To get detailed information on each option, please reference the openssl(1)
manpage. Now that we know how to invoke the OpenSSL command line,
let's have some fun!
Computing and Verifying Checksums
The Internet is used more and more frequently to distribute source
code and binary software packages. When one of the software distribution
servers is compromised, the integrity of the software packages can
come into question. To ensure that the software has not been tampered
with, a message digest can be used to create a digital fingerprint
of a file. A message digest works by running a variable-length file
through a hashing algorithm to produce a fixed-length output (the
digital fingerprint). This operation is easy to perform, but reversing
the operation is extremely difficult.
Once a fingerprint has been computed, it can be distributed to
clients through a secure channel and used to ensure that the contents
of a file have not changed.
OpenSSL supports several message digest algorithms, including:
MD2, MD4, MD5, SHA, SHA1, MDC2, and RIPEMD-160. Each algorithm can
be invoked by passing the algorithm name to the dgst command
or passed directly to the openssl command. The following
example utilizes the dgst option to compute an MD5 digest
of /etc/secure/data:
$ openssl dgst -md5 /etc/secure/data
MD5(/etc/secure/data)= f268fc3e92ef844117365a3368b8fe45
The following example passes the digest algorithm directly to openssl,
and generates an MD5 checksum of /etc/secure/data:
$ openssl md5 /etc/secure/data
MD5(/etc/secure/data)= f268fc3e92ef844117365a3368b8fe45
OpenSSL can also be combined with find to produce fingerprints
for several files:
$ find /etc -type f | xargs openssl md5 > /etc/secure/md5_sigs.txt
This will create an MD5 hash of all files in the /etc directory. If
you need to check whether a file in /etc was modified, you can compare
the current fingerprint with the fingerprint calculated above. The
file containing the fingerprints should be copied to read-only media
and stored in a safe location.
Encrypting Data
Encryption is the process of converting data (often referred to
as plaintext) to an alternate form (often referred to as ciphertext)
that is indistinguishable from the original. The data encryption
process usually requires a key and utilizes a set of algorithms
to transform the plaintext data into ciphertext.
Symmetric key algorithms (also referred to as shared secret algorithms)
utilize the same key to encrypt and decrypt data. Public key algorithms
(also referred to as asymmetric algorithms) utilize different keys
for encryption and decryption. Public key algorithms derive their
name from the fact that one of the keys (the public key) can be
distributed to others, and data encrypted with this key can only
be decrypted with the associated private key.
OpenSSL supports several symmetric key algorithms, including:
DES, 3DES, IDEA, Blowfish, and AES. Each symmetric-key algorithm
can be invoked by passing the algorithm name to the enc command
or passing it directly to the openssl command. The following
example encrypts the file named passwd with the Blowfish algorithm:
$ openssl bf -e -in /etc/secure/passwd -out /etc/secure/passwd.enc.bf
enter bf-cbc encryption password:
Verifying - enter bf-cbc encryption password
The encrypted version of passwd will be placed in /etc/secure/passwd.enc.bf.
The following example utilizes 3DES and the enc command to
encrypt the file sensitive_data. The encrypted contents are placed
in /etc/secure/sensitive_data.enc.3des:
$ openssl enc -e -3des -in /etc/secure/sensitive_data \
-out /etc/secure/sensitive_data.enc.3des
enter bf-cbc encryption password:
Verifying - enter bf-cbc encryption password:
On occasion, it may be beneficial to send the contents of an encrypted
file to a colleague or friend. The encrypted data is in binary format,
which makes it difficult to embed in email.
OpenSSL supports the base64 standard, which can be used to represent
binary data as ASCII text. To encrypt a file with the AES-128 algorithm,
and base64 encode the contents, the "-base64" and "-aes128" arguments
can be passed to openssl:
$ openssl enc -base64 -e -aes128 -in /etc/secure/data \
-out /etc/secure/data.enc.aes128.b64
enter bf-cbc encryption password:
Verifying - enter bf-cbc encryption password:
If you choose to use email or other insecure data transport facilities
to send encrypted data, it is highly recommended that you create a
digital signature or fingerprint of the encrypted file. This will
ensure that the encrypted contents have not been tampered with during
transmission.
Decrypting Data
To decrypt a file that was previously encrypted, the -d
option can be passed to the enc option or passed as an argument
to the encryption algorithm. The following example shows how to
decrypt the file /etc/secure/sensitive_data.enc.3des that was previously
encrypted with the 3DES algorithm:
$ openssl enc -des3 -d -in /etc/secure/sensitive_data.enc.3des \
-out /etc/secure/sensitive_data
This will place the decrypted file contents in the file /etc/secure/sensitive_data.
If you want to view the contents of the text file on your terminal,
the output of openssl can be piped to your favorite pager:
$ openssl enc -des3 -d -in /etc/secure/sensitive_data.enc.des3 | more
Generating Password File Entries
OpenSSL can be used to generate password hashes through the passwd
command. This facility can be used to automate user provisioning
or to conduct system-wide password updates. The following example
shows how to generate an MD5 hash of the password string "blah":
$ echo blah | openssl passwd -stdin -1
The "-1" option indicates that the MD5 message digest algorithm should
be used, and "-stdin" indicates that the passwd will be passed via
standard input. If your authentication system does not support MD5,
passwords can be created with crypt:
$ echo blah | openssl passwd -stdin -crypt -salt GH
This will generate a crypted version of the password "blah" with the
salt "GH."
Digital Certificates
A digital certificate is an electronic "drivers license" that
is used to prove the identity of a client or server. Certificate
Authorities (CAs) are responsible for issuing digital certificates
and proving the identity of the entity requesting the certificate.
Digital certificates contain several pieces of information, including:
a certificate version, a serial number to uniquely identify the
certificate, an attribute (Issuer) to identity the organization
who issued the certificate, a range of dates for which the certificate
is valid, an attribute (Subject) to identify the site to which the
certificate has been issued, and a digital signature. The digital
signature is used by clients and servers to verify the authenticity
of the certificate, and to ensure that the individual represented
by the certificate is actually who they say they are.
When an organization wants to request a digital certificate from
a certificate authority, they will need to submit a certificate-signing
request (CSR). The certificate-signing request contains a public
key, a common name (e.g., www.example.com) to uniquely identify
the site, and locality information to identify the organization.
The following example shows how to generate a certificate-signing
request:
$ openssl req -new -outform PEM -keyform PEM -keyout secret.key \
-out cert.csr -newkey rsa:1024
Generating a 1024 bit RSA private key
.............++++++
..............................................++++++
writing new private key to 'secret.key'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
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]:Georgia
Locality Name (eg, city) []:Atlanta
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:www.example.com
Email Address []: sysadmin@example.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
During the request-generation process, a 1024-bit RSA key pair is
generated and various pieces of information are gathered. The OpenSSL
utility will prompt for a pass-phrase, which is used to encrypt the
contents of the private key. Once the keys are generated, the private
key will be PEM encoded and placed in the file secret.key. The certificate-signing
request is placed in the file cert.csr. This file contains the public
key, locality information, and a common name to uniquely identify
the site. You can print the contents of the certificate-signing request
with the req command:
$ openssl -req -in cert.csr -text
Once you have verified the certificate signing request, you can submit
the contents to your favorite Certificate Authority. The certificate
authority will use the contents of this file along with their private
key to generate a digital certificate.
Displaying the Contents of a Digital Certificate
Digital certificates can be stored in several formats. Two of
the most common formats are PEM (Privacy Enhanced Mail) and DER
(Definite Encoding Rules). OpenSSL can print the contents of both
certificate formats with the x509 commands. The following example
will print the contents of the PEM-encoded certificate cert.crt.pem:
$ openssl x509 -in cert.crt.pem -inform PEM -text -noout
OpenSSL also allows you to print individual attributes of a certificate:
$ openssl x509 -in cert.crt.der -inform DER -noout -enddate
This will print just the expiration data for the certificate cert.crt.der.
Converting Between Certificate Types
As mentioned above, digital certificates can be stored in a variety
of formats. This can cause problems when a certificate needs to
be migrated between heterogeneous Web servers or distributed between
application components. OpenSSL provides the x509 option to convert
between PEM- and DER-encoded certificates. The following example
will convert a PEM-encoded certificate to DER format:
$ openssl x509 -in cert.crt.pem -inform PEM -out cert.crt.der -outform DER
Once the certificate has been converted, it will be placed in the
file cert.crt.der. The following example converts a DER-formatted
certificate to PEM format:
$ openssl x509 -in cert.crt.der -inform DER -out cert.crt.pem -outform PEM
The OpenSSL pkcs12 command can be used to import and export
certificates stored in a PKCS#12 database. The following example will
export a certificate with the alias Server-Cert from a PKCS#12 database:
$ openssl pkcs12 -export Server-Cert -in cert.db.pkcs12 -out cert.crt.p12
Once the certificate has been exported, it can be converted to PEM
or DER format with the pkcs12 command:
$ openssl pkcs12 -in cert.crt.p12 -out cert.crt.pem
Monitoring Secure Web Server Connectivity with OpenSSL
Listing 1 shows how OpenSSL can be used to check whether an SSL-enabled
Web site is handling new connections. The openssl s_client
option is invoked, and an HTTP GET request is passed to the Web
server after the SSL connection is set up. If the server fails to
return a valid response, a message is logged via syslog, and an
email is sent to the on-call pager. This script can run periodically
via cron or be modified to run continuously as a daemon at system
startup.
Checking for Expired Web Site Certificates
Digital certificates can be deployed to authenticate clients and
to prove the identity of a server. When digital certificates are
issued, an expiration date is assigned, which ensures that compromised
certificates will not have an endless lifetime. During SSL connection
establishment, clients and servers will typically check the expiration
date assigned to a certificate. When server certificates expire,
customers are presented with warning messages, which may cause confusion.
Expired certificates may also lead to service disruption. To provide
alarming capabilities to combat this problem, I developed ssl-cert-check.
Listing 2 (ssl-cert-check) is a bash script that utilizes GNU
date and the openssl s_client command-line option. ssl-cert-check
supports interactive and batch operations and can be configured
to send email when a certificate is about to expire. ssl-cert-check
will print a detailed help screen when invoked without any options:
$ ./ssl-cert-check
Usage: ./ssl-cert-check {{ [ -b ] && [ -f cert_file ] } || { \
[ -s common_name ] && [ -p port] }} [ -e email ] \
[ -x expir_days ] [ -q ] [ -a ] [ -h ]
-a : Send a warning message through email
-b : Print the expiration date for all
certificates in cert_file (batch mode)
-e email address : Email address to send expiration notices
-f cert file : File with a list of common names and ports
(eg., blatch.com 443)
-h : Print this screen
-p port : Port to connect to (interactive mode)
-s commmon name : Server to connect to (interactive mode)
-q : Don't print anything on the console
-x days : Certificate expiration interval
(eg. if cert_date < days)
The following command can be used to view the certificate expiration
date for the daemons.net Web server running on port 443:
$ ./ssl-cert-check -s www.daemons.net -p 443
Host Status Expires Days Left
www.daemons.net:443 Valid May 24 2005 363
The script can also be run in batch mode, which will cause ssl-cert-check
to process a full list of domain and TCP port combinations:
$ cat ssldomains
www.spotch.com 443
mail.daemons.net 995
www.daemons.net 443
$ ./ssl-cert-check -b -f ssldomains
Host Status Expires Days Left
www.spotch.com:443 Down ? ?
mail.daemons.net:995 Expired Oct 30 2002 -574
www.daemons.net:443 Valid May 24 2005 363
ssl-cert-check also provides capabilities to alarm (via email) when
a certificate is getting ready to expire. This capability combined
with the quiet mode of operation will allow ssl-cert-check to be easily
integrated into a scheduling facility:
$ ./ssl-cert-check -b -f ssldomains -q -a -x 90 -e matty@daemons.net
This will cause ssl-cert-check to check all the domains listed in
the file ssldomains and send email to matty@daemons.net if a certificate
will expire in 90-days or less.
Conclusion
In this article, I introduced a few examples of how OpenSSL can
be used to secure data and manage digital certificates. I also provided
two example scripts that can be used to check for certificate expiration
and the status of an SSL-enabled Web server. Large portions of most
bookstores and complete courses have been created to explain cryptography,
encryption, SSL, and TLS. This article barely scratched the surface
of what is available. As with all software, the examples should
be tested thoroughly prior to use in any production environment.
Acknowledgements
I thank the OpenSSL developers and all the folks who have put
time and energy into the design and implementation of the cryptographic
algorithms and protocols discussed in this article.
References
Web Sites:
OpenSSL: http://www.openssl.org
ssl-cert-check: http://www.daemons.net/software
TLS 1.0 RFC: http://www.ietf.org/html.charters/tls-charter.html
Books:
Schneier, Bruce. 1996. Applied Cryptography. John Wiley
& Sons.
Stallings, William. 2003. Cryptography and Network Security:
Principles and Practice. Prentice Hall.
Thomas, Stephen. 2000. SSL & TLS Essentials: Securing the
Web. John Wiley & Sons.
Viega, John; Matt Messier; and Pravir Chandra. Network Security
with OpenSSL: Cryptography for Secure Communications. O'Reilly
& Associates.
Ryan Matteson has been a UNIX systems administrator for eight
years. He specializes in network security, Web technologies, Storage
Area Networks, high-availability systems, Linux, and the Solaris
operating systems. Questions and comments about this article can
be addressed to: matty91@bellsouth.net. |