OpenSSL Command-Line HOWTO
OpenSSL Command-Line HOWTO
m a d b o a . c o m
Home
OpenSSL Command-Line HOWTO
Geek stuff
T able of Contents
Introduction
Benchmarking
Certificates
Certificate Verification
Digests
Errors
Key s
Password hashes
Prime numbers
http://www.madboa.com/geek/openssl/ 1/17
04/05/2010 OpenSSL Command-Line HOWTO
How do I test whether a number is prime?
How do I generate a set of prime numbers?
Random data
S/MIME
Introduction
The openssl command-line binary that ships with the OpenSSL libraries can perform a
wide range of cryptographic operations. It can come in handy in scripts or for
accomplishing one-time command-line tasks.
Just to be clear, this article is strictly practical; it does not concern cryptographic theory
and concepts. If you don’t know what an MD5 sum is, this article won’t enlighten you
one bit—but if all you need to know is how to use openssl to generate a file sum, you’re
in luck.
The nature of this article is that I’ll be adding new examples incrementally. Check back
at a later date if I haven’t gotten to the information you need.
Standard commands
asn1parse ca ciphers crl crl2pkcs7
dgst dh dhparam dsa dsaparam
ec ecparam enc engine errstr
gendh gendsa genrsa nseq ocsp
passwd pkcs12 pkcs7 pkcs8 prime
rand req rsa rsautl s_client
s_server s_time sess_id smime speed
spkac verify version x509
http://www.madboa.com/geek/openssl/ 2/17
04/05/2010 OpenSSL Command-Line HOWTO
Message Digest commands (see the `dgst' command for more details)
md2 md4 md5 rmd160 sha
sha1
What the shell calls “Standard commands” are the main top-level options.
In more boring fashion, you can consult the OpenSSL man pages.
# list only high encryption ciphers (keys larger than 128 bits)
openssl ciphers -v 'HIGH'
Benchmarking
How do I benchmark my system’s performance?
The OpenSSL developers have built a benchmarking suite directly into the openssl
binary. It’s accessible via the speed option. It tests how many operations it can perform
in a given time, rather than how long it takes to perform a given number of operations.
This strikes me a quite sane, because the benchmarks don’t take significantly longer to
run on a slow system than on a fast one.
http://www.madboa.com/geek/openssl/ 3/17
04/05/2010 OpenSSL Command-Line HOWTO
openssl speed
There are two sets of results. The first reports how many bytes per second can be
processed for each algorithm, the second the times needed for sign/verify cycles. Here
are the results on an 2.16GHz Intel Core 2.
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
md2 1736.10k 3726.08k 5165.04k 5692.28k 5917.35k
mdc2 0.00 0.00 0.00 0.00 0.00
md4 18799.87k 65848.23k 187776.43k 352258.73k 474622.63k
md5 16807.01k 58256.45k 160439.13k 287183.53k 375220.91k
hmac(md5) 23601.24k 74405.08k 189993.05k 309777.75k 379431.59k
sha1 16774.59k 55500.39k 142628.69k 233247.74k 288382.98k
rmd160 13854.71k 40271.23k 87613.95k 124333.06k 141781.67k
rc4 227935.60k 253366.06k 261236.94k 259858.09k 194928.50k
des cbc 48478.10k 49616.16k 49765.21k 50106.71k 50034.01k
des ede3 18387.39k 18631.02k 18699.26k 18738.18k 18718.72k
idea cbc 0.00 0.00 0.00 0.00 0.00
rc2 cbc 19247.24k 19838.12k 19904.51k 19925.33k 19834.98k
rc5-32/12 cbc 0.00 0.00 0.00 0.00 0.00
blowfish cbc 79577.50k 83067.03k 84676.78k 84850.01k 85063.00k
cast cbc 45362.14k 48343.34k 49007.36k 49202.52k 49225.73k
aes-128 cbc 58751.94k 94443.86k 111424.09k 116704.26k 117997.57k
aes-192 cbc 53451.79k 82076.22k 94609.83k 98496.85k 99150.51k
aes-256 cbc 49225.21k 72779.84k 82266.88k 85054.81k 85762.05k
sha256 9359.24k 22510.83k 40963.75k 51710.29k 56014.17k
sha512 7026.78k 28121.32k 54330.79k 86190.76k 104270.51k
sign verify sign/s verify/s
rsa 512 bits 0.000522s 0.000042s 1915.8 23969.9
rsa 1024 bits 0.002321s 0.000109s 430.8 9191.1
rsa 2048 bits 0.012883s 0.000329s 77.6 3039.6
rsa 4096 bits 0.079055s 0.001074s 12.6 931.3
sign verify sign/s verify/s
dsa 512 bits 0.000380s 0.000472s 2629.3 2117.9
dsa 1024 bits 0.001031s 0.001240s 969.6 806.2
dsa 2048 bits 0.003175s 0.003744s 314.9 267.1
Beyond that most simple invocation, s_time gives you a wide variety of testing options.
http://www.madboa.com/geek/openssl/ 4/17
04/05/2010 OpenSSL Command-Line HOWTO
echo
done
If you don’t have an SSL-enabled web server available for your use, you can emulate one
using the s_server option.
Certificates
How do I generate a self-signed certificate?
Y ou’ll first need to decide whether or not you want to encrypt your key. Doing so means
that the key is protected by a passphrase.
On the plus side, adding a passphrase to a key makes it more secure, so the key is less
likely to be useful to someone who steals it. The downside, however, is that you’ll have to
either store the passphrase in a file or type it manually every time you want to start your
web or ldap server.
It violates my normally paranoid nature to say it, but I prefer unencrypted keys, so I
don’t have to manually type a passphrase each time a secure daemon is started. (It’s not
terribly difficult to decrypt your key if you later tire of typing a passphrase.)
This example will produce a file called mycert.pem which will contain both the private
key and the public certificate based on it. The certificate will be valid for 365 days, and
the key (thanks to the -nodes option) is unencrypted.
openssl req \
-x509 -nodes -days 365 \
-newkey rsa:1024 -keyout mycert.pem -out mycert.pem
Using this command-line invocation, you’ll have to answer a lot of questions: Country
Name, State, City, and so on. The tricky question is “Common Name.” Y ou’ll want to
answer with the hostname or CNAME by which people will address the server. This is
very important. If your web server’s real hostname is mybox.mydomain.com but people
will be using www.mydomain.com to address the box, then use the latter name to answer
the “Common Name” question.
Once you’re comfortable with the answers you provide to those questions, you can script
the whole thing by adding the -subj option. I’ve included some information about
location into the example that follows, but the only thing you really need to include for
the certificate to be useful is the hostname (CN).
openssl req \
-x509 -nodes -days 365 \
-subj '/C=US/ST=Oregon/L=Portland/CN=www.madboa.com' \
-newkey rsa:1024 -keyout mycert.pem -out mycert.pem
As in the recipe for creating a self-signed certificate, you’ll have to decide whether or not
you want a passphrase on your private key. The recipe below assumes you don’t. Y ou’ll
end up with two files: a new private key called mykey.pem and a certificate request called
myreq.pem.
openssl req \
-new -newkey rsa:1024 -nodes \
-keyout mykey.pem -out myreq.pem
http://www.madboa.com/geek/openssl/ 5/17
04/05/2010 OpenSSL Command-Line HOWTO
If you’ve already got a key and would like to use it for generating the request, the syntax
is a bit simpler.
Similarly, you can also provide subject information on the command line.
openssl req \
-new -newkey rsa:1024 -nodes \
-subj '/CN=www.mydom.com/O=My Dom, Inc./C=US/ST=Oregon/L=Portland' \
-keyout mykey.pem -out myreq.pem
When dealing with an institution like VeriSign, you need to take special care to make
sure that the information you provide during the creation of the certificate request is
exactly correct. I know from personal experience that even a difference as trivial as
substituting “and” for “&” in the Organization Name will stall the process.
If you’d like, you can double check the signature and information provided in the
certificate request.
# verify signature
openssl req -in myreq.pem -noout -verify -key mykey.pem
# check info
openssl req -in myreq.pem -noout -text
Save the key file in a secure location. Y ou’ll need it in order to use the certificate VeriSign
sends you. The certificate request will typically be pasted into VeriSign’s online
application form.
First, launch the test server on the machine on which the certificate will be used. By
default, the server will listen on port 4433; you can alter that using the -accept option.
If the server launches without complaint, then chances are good that the certificate is
ready for production use.
Y ou can also point your web browser at the test server, e.g.,
https://yourserver:4433/. Don’t forget to specify the “https” protocol; plain-old “http”
won’t work. Y ou should see a page listing the various ciphers available and some
statistics about your connection. Most modern browsers allow you to examine the
certificate as well.
#!/bin/sh
#
# usage: retrieve-cert.sh remote.host.name [port]
#
REMHOST=$1
REMPORT=${2:-443}
echo |\
openssl s_client -connect ${REMHOST}:${REMPORT} 2>&1 |\
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'
Y ou can, in turn, pipe that information back to openssl to do things like check the dates
on all your active certificates.
#!/bin/sh
http://www.madboa.com/geek/openssl/ 6/17
04/05/2010 OpenSSL Command-Line HOWTO
#
for CERT in \
www.yourdomain.com:443 \
ldap.yourdomain.com:636 \
imap.yourdomain.com:993 \
do
echo |\
openssl s_client -connect ${CERT} 2>/dev/null |\
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' |\
openssl x509 -noout -subject -dates
done
Using the -text option will give you the full breadth of information.
To create a PKCS#12 certificate, you’ll need a private key and a certificate. During the
conversion process, you’ll be given an opportunity to put an “Export Password” (which
can be empty, if you choose) on the certificate.
If someone sends you a PKCS#12 and any passwords needed to work with it, you can
export it into standard PEM format.
http://www.madboa.com/geek/openssl/ 7/17
04/05/2010 OpenSSL Command-Line HOWTO
Certificate Verification
Applications linked against the OpenSSL libraries can verify certificates signed by a
recognized certificate authority (CA).
If your local OpenSSL installation recognizes the certificate or its signing authority and
everything else (dates, signing chain, etc.) checks out, you’ll get a simple OK message.
$ openssl verify remote.site.pem
remote.site.pem: OK
If anything is amiss, you’ll see some error messages with short descriptions of the
problem, e.g.,
The default location for this directory is /usr/local/ssl, but most vendors put it
elsewhere, e.g., /usr/share/ssl (Red Hat/Fedora), /etc/ssl (Gentoo), /usr/lib/ssl
(Debian), or /System/Library/OpenSSL (Macintosh OS X).
Use the version option to identify which directory (labeled OPENSSLDIR) your
installation uses.
openssl version -d
Within that directory and a subdirectory called certs, you’re likely to find one or more of
three different kinds of files.
2. Some small files in the certs subdirectory named with a .pem file extension, each
of which contains a certificate from a single CA.
3. Some symlinks in the certs subdirectory with obscure filenames like 052eae11.0.
There is typically one of these links for each .pem file.
The first part of obscure filename is actually a hash value based on the certificate
within the .pem file to which it points. The file extension is just an iterator, since it’s
theoretically possible that multiple certificates can generate identical hashes.
When an application encounters a remote certificate, it will typically check to see if the
cert can be found in cert.pem or, if not, in a file named after the certificate’s hash value.
If found, the certificate is considered verified.
http://www.madboa.com/geek/openssl/ 8/17
04/05/2010 OpenSSL Command-Line HOWTO
It’s interesting to note that some applications, like Sendmail, allow you to specify at
runtime the location of the certificates you trust, while others, like Pine, do not.
#!/bin/sh
#
# usage: certlink.sh filename [filename ...]
In this section, I assume you are familiar with the specific protocols at issue: SMTP,
HTTP, etc. Explaining them is out of the scope of this article.
Secure SMTP servers offer secure connections on up to three ports: 25 (TLS), 465 (SSL),
and 587 (TLS). Some time around the 0.9.7 release, the openssl binary was given the
ability to use STARTTLS when talking to SMTP servers.
# port 465/SSL
openssl s_client -connect remote.host:465
RFC821 suggests (although it falls short of explicitly specifying) the two characters
"<CRLF>" as line-terminator. Most mail agents do not care about this and accept either
"<LF>" or "<CRLF>" as line-terminators, but Qmail does not. If you want to comply to
the letter with RFC821 and/or communicate with Qmail, use also the -crlf option:
http://www.madboa.com/geek/openssl/ 9/17
04/05/2010 OpenSSL Command-Line HOWTO
The s_server option works best when you have a certificate; it’s fairly limited without
one.
Digests
Generating digests with the dgst option is one of the more straightforward tasks you can
accomplish with the openssl binary. Producing digests is done so often, as a matter of
fact, that you can find special-use binaries for doing the same thing.
# MD5 digest
openssl dgst -md5 filename
# SHA1 digest
openssl dgst -sha1 filename
The MD5 digests are identical to those created with the widely available md5sum
command, though the output formats differ.
$ openssl dgst -md5 foo-2.23.tar.gz
MD5(foo-2.23.tar.gz)= 81eda7985e99d28acd6d286aa0e13e07
$ md5sum foo-2.23.tar.gz
81eda7985e99d28acd6d286aa0e13e07 foo-2.23.tar.gz
The same is true for SHA1 digests and the output of the sha1sum application.
$ openssl dgst -sha1 foo-2.23.tar.gz
SHA1(foo-2.23.tar.gz)= e4eabc78894e2c204d788521812497e021f45c08
$ sha1sum foo-2.23.tar.gz
e4eabc78894e2c204d788521812497e021f45c08 foo-2.23.tar.gz
To verify a signed digest you’ll need the file from which the digest was derived, the signed
digest, and the signer’s public key.
The format of the password database is relatively simple: a colon-separated list of the
username, authorization realm (specified by the Apache AuthName directive), and an
MD5 digest of those two items and the password. Below is a script that duplicates the
output of htdigest, except that the output is written to standard output. It takes
advantage of the dgst option’s ability to read from standard input.
#!/bin/bash
printf "\n%s:%s:%s\n" \
"$UNAME" \
"$AUTHNAME" \
$(printf "${UNAME}:${AUTHNAME}:${PWORD}" | openssl dgst -md5)
openssl list-message-digest-commands
Encryption/Decryption
How do I base64-encode something?
Use the enc -base64 option.
Note that echo will silently attach a newline character to your string. Consider using its
-n option if you want to avoid that situation, which could be important if you’re trying to
encode a password or authentication string.
$ echo -n "encode me" | openssl enc -base64
ZW5jb2RlIG1l
http://www.madboa.com/geek/openssl/ 11/17
04/05/2010 OpenSSL Command-Line HOWTO
Use the -d (decode) option to reverse the process.
$ echo "ZW5jb2RlIG1lCg==" | openssl enc -base64 -d
encode me
To choose a cipher, consult the enc(1) man page. More simply (and perhaps more
accurately), you can ask openssl for a list in one of two ways.
After you choose a cipher, you’ll also have to decide if you want to base64-encode the
data. Doing so will mean the encrypted data can be, say, pasted into an email message.
Otherwise, the output will be a binary file.
# the same, only the output is base64 encoded for, e.g., e-mail
openssl enc -aes-256-cbc -a -salt -in file.txt -out file.enc
To decrypt file.enc you or the file’s recipient will need to remember the cipher and the
passphrase.
If you’d like to avoid typing a passphrase every time you encrypt or decrypt a file, the
openssl(1) man page provides the details under the heading “PASS PHRASE
ARGUMENTS.” The format of the password argument is fairly simple.
Errors
How do I interpret SSL error messages?
Poking through your system logs, you see some error messages that are evidently related
to OpenSSL or crypto:
The first step to figure out what’s going wrong is to use the errstr option to intrepret the
error code. The code number is found between “error:” and “:lib”. In this case, it’s
0407006A.
$ openssl errstr 0407006A
error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01
If you’ve got a full OpenSSL installation, including all the development documentation,
http://www.madboa.com/geek/openssl/ 12/17
04/05/2010 OpenSSL Command-Line HOWTO
you can start your investigation there. In this example, the
RSA_padding_add_PKCS1_type_1(3) man page will inform you that PKCS #1 involves
block methods for signatures. After that, of course, you’d need to pore through your
application’s source code to identify when it would expect be receiving those sorts of
packets.
Keys
How do I generate an RSA key?
Use the genrsa option.
If you’re only going to build a single DSA key, you can do so in just one step using the
dsaparam subcommand.
If, on the other hand, you’ll be creating several DSA keys, you’ll probably want to build a
shared parameter file before generating the keys. It can take a while to build the
parameters, but once built, key generation is done quickly.
http://www.madboa.com/geek/openssl/ 13/17
04/05/2010 OpenSSL Command-Line HOWTO
If you created an RSA key and it is stored in a standalone file called key.pem, then here’s
how to output a decrypted version of the same key to a file called newkey.pem.
Often, you’ll have your private key and public certificate stored in the same file. If they
are stored in a file called mycert.pem, you can construct a decrypted version called
newcert.pem in two steps.
Password hashes
Using the passwd option, you can generate password hashes that interoperate with
traditional /etc/passwd files, newer-style /etc/shadow files, and Apache password files.
If you know an existing password’s “salt,” you can duplicate the hash.
$ openssl passwd -salt 8E MySecret
8E4vqBR4UOYF.
The salt in this format consists of the eight characters between the second and third
dollar signs, in this case sXiKzkus. So you can also duplicate a hash with a known salt
and password.
$ openssl passwd -1 -salt sXiKzkus MySecret
$1$sXiKzkus$haDZ9JpVrRHBznY5OxB82.
Prime numbers
Current cryptographic techniques rely heavily on the generation and testing of prime
numbers, so it’s no surprise that the OpenSSL libraries contain several routines dealing
with primes. Beginning with version 0.9.7e (or so), the prime option was added to the
openssl binary.
Random data
How do I generate random data?
Use the rand option to generate binary or base64-encoded data.
On a Unix box with a /dev/urandom device and a copy of GNU head, you can achieve a
similar effect, often with better entropy:
Make sure you know the trade-offs between the random and urandom devices before
relying on them for truly critical entropy. Consult the random(4) man page on Linux
and BSD systems, or random(7D) on Solaris, for further information.
S/MIME
S/MIME is a standard for sending and receiving secure MIME data, especially in e-mail
messages. Automated S/MIME capabilities have been added to quite a few e-mail clients,
though openssl can provide command-line S/MIME services using the smime option.
Note that the documentation in the smime(1) man page includes a number of good
examples.
If the messages has been modified by an unauthorized party, the output will conclude
with a failure message indicating that the digest and/or the signature doesn’t match
what you received:
Verification failure
23016:error:21071065:PKCS7 routines:PKCS7_signatureVerify:digest
failure:pk7_doit.c:804:
23016:error:21075069:PKCS7 routines:PKCS7_verify:signature
failure:pk7_smime.c:265:
Likewise, if the sender’s certificate isn’t recognized by your OpenSSL infrastructure, you’ll
get a similar error:
Verification failure
9544:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify
http://www.madboa.com/geek/openssl/ 15/17
04/05/2010 OpenSSL Command-Line HOWTO
error:pk7_smime.c:222:Verify error:self signed certificate
Most e-mail clients send a copy of the public certificate in the signature attached to the
message. From the command line, you can view the certificate data yourself. Y ou’ll use
the smime -pk7out option to pipe a copy of the PKCS#7 certificate back into the pkcs7
option. It’s oddly cumbersome but it works.
If you’d like to extract a copy of your correspondent’s certificate for long-term use, use
just the first part of that pipe.
At that point, you can either integrate it into your OpenSSL infrastructure or you can
save it off somewhere for special use.
To get the default—though fairly weak—RC2-40 encryption, you just tell openssl where
the message and the certificate are located.
If you’re pretty sure your remote correspondent has a robust SSL toolkit, you can specify
a stronger encryption algorithm like triple DES:
By default, the encrypted message, including the mail headers, is sent to standard output.
Use the -out option or your shell to redirect it to a file. Or, much trickier, pipe the output
directly to sendmail.
openssl smime \
-sign \
-signer /path/to/your-cert.pem \
-in my-message.txt \
-from 'Your Fullname <[email protected]>' \
-to 'Her Fullname <[email protected]>' \
-subject 'My signed reply' |\
sendmail [email protected]
http://www.madboa.com/geek/openssl/ 16/17
04/05/2010 OpenSSL Command-Line HOWTO
OpenSSL man pages are the best place to start: asn1parse(1), ca(1), ciphers(1), config(5),
crl(1), crl2pkcs7(1), dgst(1), dhparam(1), dsa(1), dsaparam(1), ec(1), ecparam(1), enc(1),
errstr(1), gendsa(1), genpkey(1), genrsa(1), nseq(1), ocsp(1), openssl(1), passwd(1),
pkcs12(1), pkcs7(1), pkcs8(1), pkey(1), pkeyparam(1), pkeyutl(1), rand(1), req(1), rsa(1),
rsautl(1), s_client(1), s_server(1), s_time(1), sess_id(1), smime(1), speed(1), spkac(1),
ts(1), tsget(1), verify(1), version(1), x509(1), x509v3_config(5).
Comments welcome
Comments and suggestions about this document are appreciated and can be addressed to
the author at <[email protected]>.
http://www.madboa.com/geek/openssl/ 17/17