Monday, December 06, 2004


madboa.com


OpenSSL Command-Line HOWTO
Paul Heinlein


December 2, 2004


The openssl application that ships with the OpenSSL libraries can perform a
wide range of crypto operations. This HOWTO provides some cookbook-style
recipes for using it.





Table of Contents


Introduction
How do I find out what OpenSSL version I'm running?
How do I get a list of the available commands?
How do I get a list of available ciphers?
Benchmarking
How do I benchmark my system's performance?
How do I benchmark remote connections?
Certificates
How do I generate a self-signed certificate?
How do I generate a certificate request for VeriSign?
How do I test a new certificate?
How do I retrieve a remote certificate?
How do I extract information from a certificate?
How do I export or import a PKCS#12 certificate?
Certificate Verification
How do I verify a certificate?
What certificate authorities does OpenSSL recognize?
How do I get OpenSSL to recognize/verify a certificate?
Command-line clients and servers
How do I connect to a secure SMTP server?
How do I connect to a secure [whatever] server?
How do I set up an SSL server from the command line?
Digests
How do I create an MD5 or SHA1 digest of a file?
How do I sign a digest?
How do I verify a signed digest?
What other kinds of digests are available?
Encryption/Decryption
How do I base64-encode something?
How do I simply encrypt a file?
Keys
How do I generate an RSA key?
How do I generate a public RSA key?
How do I generate a DSA key?
How do I remove a passphrase from a key?
Password hashes
How do I generate a crypt-style password hash?
How do I generate a shadow-style password hash?
Random data
How do I generate random bits?
S/MIME
How do I encrypt a S/MIME message?
How do I sign a S/MIME message?
How do I verify a signed S/MIME message?
For further reading
Comments welcome
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.


Documentation for using the openssl application is somewhat scattered,
however, so this article aims to provide some practical examples of its
use. I assume that you've already got a functional OpenSSL installation and
that the openssl binary is in your shell's PATH.


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.


How do I find out what OpenSSL version I'm running?


Use the version option.


$ openssl version
OpenSSL 0.9.7d 17 Mar 2004

How do I get a list of the available commands?


There are three built-in options for getting lists of available commands,
but none of them provide what I consider useful output. The best thing to
do is provide an invalid command (help or -h will do nicely) to get a
readable answer.


$ 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 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 rc2 rc2-40-cbc
rc2-64-cbc rc2-cbc rc2-cfb rc2-ecb rc2-ofb
rc4 rc4-40



What the shell calls "Standard commands" are the main top-level options.


You can use the same trick with any of the subcommands.


$ openssl dgst -h
unknown option '-h'
options are
-c to output the digest with separating colons
-d to output debug info
-hex output as hex dump
-binary output in binary form
-sign file sign digest using private key in file
-verify file verify a signature using public key in file
-prverify file verify a signature using private key in file
-keyform arg key file format (PEM or ENGINE)
-signature file signature to verify
-binary output in binary form
-engine e use engine e, possibly a hardware device.
-md5 to use the md5 message digest algorithm (default)
-md4 to use the md4 message digest algorithm
-md2 to use the md2 message digest algorithm
-sha1 to use the sha1 message digest algorithm
-sha to use the sha message digest algorithm
-mdc2 to use the mdc2 message digest algorithm
-ripemd160 to use the ripemd160 message digest algorithm



In more boring fashion, you can consult the OpenSSL man pages.


How do I get a list of available ciphers?


Use the ciphers option. The ciphers(1) man page is quite helpful.


# list all available ciphers
openssl ciphers -v

# list only TLSv1 ciphers
openssl ciphers -v -tls1

# list only high encryption ciphers (keys larger than 128 bits)
openssl ciphers -v 'HIGH'

# list only high encryption ciphers using the AES algorithm
openssl ciphers -v 'AES+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.


To run a catchall benchmark, run it without any further options.


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 866MHz Pentium III.


The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192
bytes
md2 670.66k 1426.54k 1992.36k 2213.89k
2291.03k
mdc2 0.00 0.00 0.00 0.00
0.00
md4 6125.45k 21351.38k 60480.17k 111804.42k
149312.30k
md5 5193.06k 18369.35k 53073.32k 100135.94k
135624.02k
hmac(md5) 3041.32k 11279.21k 36399.53k 82535.42k
128502.44k
sha1 4964.28k 15264.32k 36865.37k 56804.01k
67289.09k
rmd160 4668.18k 13871.53k 30900.74k 44740.61k
51590.49k
rc4 80531.08k 90495.68k 96069.21k 97128.79k
95857.32k
des cbc 17984.00k 18767.62k 18894.34k 19037.87k
19049.13k
des ede3 6622.08k 6758.36k 6824.11k 6781.95k
6832.13k
idea cbc 0.00 0.00 0.00 0.00
0.00
rc2 cbc 7148.38k 7361.83k 7430.14k 7442.77k
7451.99k
rc5-32/12 cbc 0.00 0.00 0.00 0.00
0.00
blowfish cbc 28184.34k 30013.45k 30568.87k 30514.86k
30743.29k
cast cbc 15924.76k 17093.03k 17436.67k 17531.22k
17487.19k
aes-128 cbc 15880.95k 16398.36k 16509.10k 16560.81k
16569.69k
aes-192 cbc 13653.11k 14207.34k 14279.08k 14312.11k
14333.27k
aes-256 cbc 12320.43k 12614.25k 12673.62k 12717.40k
12678.49k
sign verify sign/s verify/s
rsa 512 bits 0.0017s 0.0002s 577.1 6452.1
rsa 1024 bits 0.0083s 0.0004s 121.2 2300.5
rsa 2048 bits 0.0484s 0.0014s 20.7 701.2
rsa 4096 bits 0.3252s 0.0050s 3.1 201.5
sign verify sign/s verify/s
dsa 512 bits 0.0014s 0.0017s 714.0 598.8
dsa 1024 bits 0.0041s 0.0050s 246.5 199.2
dsa 2048 bits 0.0135s 0.0164s 74.0 60.8



You can run any of the algorithm-specific subtests directly.


# test rsa speeds
openssl speed rsa

# do the same test on a two-way SMP system
openssl speed rsa -multi 2

How do I benchmark remote connections?


The s_time option lets you test connection performance. The most simple
invocation will run for 30 seconds, use any cipher, and use SSL handshaking
to determine number of connections per second, using both new and reused
sessions:


openssl s_time -connect remote.host:443



Beyond that most simple invocation, s_time gives you a wide variety of
testing options.


# retrieve remote test.html page using only new sessions
openssl s_time -connect remote.host:443 -www /test.html -new

# similar, using only SSL v3 and high encryption (see
# ciphers(1) man page for cipher strings)
openssl s_time -connect remote.host:443 -www /test.html -new -ssl3 -cipher HIGH

# compare relative performance of various ciphers in
# 10-second tests
IFS=":"
for c in $(openssl ciphers -ssl3 RSA); do
echo $c
openssl s_time -connect remote.host:443 -www / -new -time 10 -cipher $c 2>&1 | grep bytes
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.


# on one host, set up the server (using default port 4433)
openssl s_server -cert mycert.pem -www

# on second host (or even the same one), run s_time
openssl s_time -connect myhost:4433 -www / -new -ssl3

Certificates
How do I generate a self-signed certificate?


You'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." You'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

How do I generate a certificate request for VeriSign?


Applying for a certificate signed by a recognized certificate authority
like VeriSign is a complex bureaucratic process. You've got to perform all
the requisite paperwork before creating a certificate request.


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. You'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



If you've already got a key and would like to use it for generating the
request, the syntax is a bit simpler.


openssl req -new -key mykey.pem -out myreq.pem



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. You'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.


How do I test a new certificate?


The s_server option provides a simple but effective testing method. The
example below assumes you've combined your key and certificate into one
file called mycert.pem.


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.


openssl s_server -cert mycert.pem -www



If the server launches without complaint, then chances are good that the
certificate is ready for production use.


You 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. You 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.


How do I retrieve a remote certificate?


If you combine openssl and sed, you can retrieve remote certificates via a
shell one-liner or a simple script.


#!/bin/sh
#
# usage: retrieve-cert.sh remote.host.name [port]
#
REMHOST=$1
REMPORT=${2:-443}

openssl s_client -connect ${REMHOST}:${REMPORT} 2>&1 |sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'



You'll typically have to press Ctrl+C to close the script, since the remote
server is probably waiting for some sort of input.


How do I extract information from a certificate?


An SSL certificate contains a wide range of information: issuer, valid
dates, subject, and some hardcore crypto stuff. The x509 subcommand is the
entry point for retrieving this information. The examples below all assume
that the certificate you want to examine is stored in a file named cert.pem
.


Using the -text option will give you the full breadth of information.


openssl x509 -text -in cert.pem



Other options will provide more targeted sets of data.


# who issued the cert?
openssl x509 -noout -in cert.pem -issuer

# to whom was it issued?
openssl x509 -noout -in cert.pem -subject

# for what dates is it valid?
openssl x509 -noout -in cert.pem -dates

# the above, all at once
openssl x509 -noout -in cert.pem -issuer -subject -dates

# what is its hash value?
openssl x509 -noout -in cert.pem -hash

# what is its MD5 fingerprint?
openssl x509 -noout -in cert.pem -fingerprint

How do I export or import a PKCS#12 certificate?


PKCS#12 files can be imported and exported by a number of applications,
including Microsoft IIS. They are often associated with the file extension
.pfx.


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.


# create a file containing key and self-signed certificate
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout mycert.pem -out mycert.pem

# export mycert.pem as PKCS#12 file, mycert.pfx
openssl pkcs12 -export -out mycert.pfx -in mycert.pem -name "My Certificate"



If someone sends you a PKCS#12 and any passwords needed to work with it,
you can export it into standard PEM format.


# export certificate and passphrase-less key
openssl pkcs12 -in mycert.pfx -out mycert.pem -nodes

# same as above, but you'll be prompted for a passphrase for
# the private key
openssl pkcs12 -in mycert.pfx -out mycert.pem

Certificate Verification


Applications linked against the OpenSSL libraries can verify certificates
signed by a recognized certificate authority (CA).


How do I verify a certificate?


Use the verify option to verify certificates.


openssl verify cert.pem



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.,
error 10 at 0 depth lookup:certificate has expired. Certificates are
typically issued for a limited period of time?usually just one
year?and openssl will complain if a certificate has expired.
error 18 at 0 depth lookup:self signed certificate. Unless you make an
exception, OpenSSL won't verify a self-signed certificate.


What certificate authorities does OpenSSL recognize?


When OpenSSL was built for your system, it was configured with a "Directory
for OpenSSL files." (That's the --openssldir option passed to the configure
script, for you hands-on types.) This is the directory that typically holds
information about certificate authorities your system trusts.


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),
or /usr/lib/ssl (Debian).


I don't know of any built-in method for identifying the location of this
directory, but here's a hack that'll work on Linux systems.


strace openssl verify /some/file 2>&1 | grep cert.pem



On Solaris systems, use truss instead of strace. Either way, you should see
a reference to the OpenSSL directory. Here's a system where it's /etc/ssl:


$ strace openssl verify /some/file 2>&1 | grep cert.pem
open("/etc/ssl/cert.pem", O_RDONLY) = 3



Within that directory and a subdirectory called certs, you're likely to
find one or more of three different kinds of files.
1. A large file called cert.pem, an omnibus collection of many
certificates from recognized certificate authorities like VeriSign and
Thawte.
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.


On my Gentoo system, for example, there's a symlink named f73e89fd.0
that points to a file named vsignss.pem. Sure enough, the certificate
in that file generates a hash the equates to the name of the symlink:


$ openssl x509 -noout -hash -in vsignss.pem
f73e89fd



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.


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.


How do I get OpenSSL to recognize/verify a certificate?


Put the file that contains the certificate you'd like to trust into the
certs directory discussed above. Then create the hash-based symlink. Here's
a little script that'll do just that.


#!/bin/sh
#
# usage: certlink.sh filename [filename ...]

for CERTFILE in $*; do
# make sure file exists and is a valid cert
test -f "$CERTFILE" || continue
HASH=$(openssl x509 -noout -hash -in "$CERTFILE")
test -n "$HASH" || continue

# use lowest available iterator for symlink
for ITER in 0 1 2 3 4 5 6 7 8 9; do
test -f "${HASH}.${ITER}" && continue
ln -s "$CERTFILE" "${HASH}.${ITER}"
test -L "${HASH}.${ITER}" && break
done
done

Command-line clients and servers


The s_client and s_server options provide a way to launch SSL-enabled
command-line clients and servers. There are other examples of their use
scattered around this document, but this section is dedicated solely to
them.


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.


How do I connect to a secure SMTP server?


You can test, or even use, an SSL-enabled SMTP server from the command line
using the s_client option.


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 25/TLS; use same syntax for port 587
openssl s_client -connect remote.host:25 -starttls smtp

# port 465/SSL
openssl s_client -connect remote.host:465

How do I connect to a secure [whatever] server?


Connecting to a different type of SSL-enabled server is essentially the
same operation as outlined above. As of the date of this writing, openssl
only supports command-line TLS with SMTP servers, so you have to use
straightforward SSL connections with any other protocol.


# https: HTTP over SSL
openssl s_client -connect remote.host:443

# ldaps: LDAP over SSL
openssl s_client -connect remote.host:636

# imaps: IMAP over SSL
openssl s_client -connect remote.host:993

# pop3s: POP-3 over SSL
openssl s_client -connect remote.host:995

How do I set up an SSL server from the command line?


The s_server option allows you to set up an SSL-enabled server from the
command line, but it's I wouldn't recommend using it for anything other
than testing or debugging. If you need a production-quality wrapper around
an otherwise insecure server, check out Stunnel instead.


The s_server option works best when you have a certificate; it's fairly
limited without one.


# the -www option will sent back an HTML-formatted status page
# to any HTTP clients that request a page
openssl s_server -cert mycert.pem -www

# the -WWW option "emulates a simple web server. Pages will be
# resolved relative to the current directory." This example
# is listening on the https port, rather than the default
# port 4433
openssl s_server -accept 443 -cert mycert.pem -WWW

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.


How do I create an MD5 or SHA1 digest of a file?


Digests are created using the dgst option.


# MD5 digest
openssl dgst -md5 filename

# SHA1 digest
openssl dgst -sha1 filename



The MD5 digests are indentical 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

How do I sign a digest?


If you want to ensure that the digest you create doesn't get modified
without your permission, you can sign it using your private key. The
following example assumes that you want to sign the SHA1 sum of a file
called foo-1.23.tar.gz.


# signed digest will be foo-1.23.tar.gz.sha1
openssl dgst -sha1 -sign mykey.pem
-out foo-1.23.tar.gz.sha1 foo-1.23.tar.gz

How do I verify a signed digest?


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.


# to verify foo-1.23.tar.gz using foo-1.23.tar.gz.sha1
# and pubkey.pem
openssl dgst -sha1 -verify pubkey.pem -signature foo-1.23.tar.gz.sha1 foo-1.23.tar.gz

What other kinds of digests are available?


Use the built-in list-message-digest-commands option to get a list of the
digest types available to your local OpenSSL installation.


openssl list-message-digest-commands

Encryption/Decryption
How do I base64-encode something?


Use the enc -base64 option.


# send encoded contents of file.txt to stdout
openssl enc -base64 -in file.txt

# same, but write contents to file.txt.enc
openssl enc -base64 -in file.txt -out file.txt.enc



It's also possible to do a quick command-line encoding of a string value:


$ echo "encode me" | openssl enc -base64
ZW5jb2RlIG1lCg==



Use the -d (decode) option to reverse the process.


$ echo "ZW5jb2RlIG1lCg==" | openssl enc -base64 -d
encode me

How do I simply encrypt a file?


Simple file encryption is probably better done using a tool like GPG.
Still, you may have occasion to want to encrypt a file without having to
build or use a key/certificate structure. All you want to have to remember
is a password. It can nearly be that simple?if you can also remember the
cipher you employed for encryption.


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.


# see the list under the 'Cipher commands' heading
openssl -h

# or get a long list, one cipher per line
openssl list-cipher-commands



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.


# encrypt file.txt to file.enc using 256-bit AES in CBC mode
openssl enc -aes-256-cbc -salt -in file.txt -out file.enc

# 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.


# decrypt binary file.enc
openssl enc -d -aes-256-cbc -in file.enc

# decrypt base64-encoded version
openssl enc -d -aes-256-cbc -a -in file.enc

Keys
How do I generate an RSA key?


Use the genrsa option.


# default 512-bit key, sent to standard output
openssl genrsa

# 1024-bit key, saved to file named mykey.pem
openssl genrsa -out mykey.pem 1024

# same as above, but encrypted with a passphrase
openssl genrsa -des3 -out mykey.pem 1024

How do I generate a public RSA key?


Use the rsa option to produce a public version of your private RSA key.


openssl rsa -in mykey.pem -pubout

How do I generate a DSA key?


Building DSA keys requires a parameter file, and DSA verify operations are
slower than their RSA counterparts, so they aren't as widely used as RSA
keys.


If you're only going to build a single DSA key, you can do so in just one
step using the dsaparam subcommand.


# key will be called dsakey.pem
openssl dsaparam -noout -out dsakey.pem -genkey 1024



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.


# create parameters in dsaparam.pem
openssl dsaparam -out dsaparam.pem 1024

# create first key
openssl gendsa -out key1.pem dsaparam.pem

# and second ...
openssl gendsa -out key2.pem dsaparam.pem

How do I remove a passphrase from a key?


Perhaps you've grown tired of typing your passphrase every time your secure
daemon starts. You can decrypt your key, removing the passphrase
requirement, using the rsa or dsa option, depending on the signature
algorithm you chose when creating your private key.


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.


# you'll be prompted for your passphrase one last time
openssl rsa -in key.pem -out 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.


# you'll need to type your passphrase once more
openssl rsa -in mycert.pem -out newcert.pem
openssl x509 -in mycert.pem >>newcert.pem

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.


How do I generate a crypt-style password hash?


You can generate a new hash quite simply:


$ openssl passwd MySecret
8E4vqBR4UOYF.



If you know an existing password's "salt," you can duplicate the hash.


$ openssl passwd -salt 8E MySecret
8E4vqBR4UOYF.

How do I generate a shadow-style password hash?


Newer Unix systems use a more secure MD5-based hashing mechanism that uses
an eight-character salt (as compared to the two-character salt in
traditional crypt()-style hashes). Generating them is still straightforward
using the -1 option:


$ openssl passwd -1 MySecret
$1$sXiKzkus$haDZ9JpVrRHBznY5OxB82.



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.

Random data
How do I generate random bits?


Use the rand option to generate binary or base64-encoded data.


# write 128 random bits of base64-encoded data to stdout
openssl rand -base64 128

# write 1024 bits of binary random data to a file
openssl rand -out random-data.bin 1024

# seed openssl with semi-random bytes from browser cache
cd $(find ~/.mozilla/firefox -type d -name Cache)
openssl rand -rand $(find . -type f -printf '%f:') -base64 1024

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.


How do I encrypt a S/MIME message?


Let's say that someone sends you her public certificate and asks that you
encrypt some message to her. You've saved her certificate as her-cert.pem.
You've saved your reply as my-message.txt.


To get the default?though fairly weak?RC2-40 encryption, you just tell
openssl where the message and the certificate are located.


openssl smime -encrypt -in my-message.txt her-cert.pem



If you're pretty sure your remote correspondent has a robust SSL toolkit,
you can specify a stronger encryption algorithm like triple DES:


openssl smime -encrypt -des3 -in my-message.txt her-cert.pem



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 her-cert.pem -encrypt -des3 -in my-message.txt -from 'Your Fullname ' -to 'Her Fullname ' -subject 'My encrypted reply' |sendmail her@heraddress.com

How do I sign a S/MIME message?


If you don't need to encrypt the entire message, but you do want to sign it
so that your recipient can be assured of the message's integrity, the
recipe is similar to that for encryption. The main difference is that you
need to have your own key and certificate, since you can't sign anything
with the recipient's cert.


openssl smime -sign -signer /path/to/your-cert.pem -in my-message.txt -from 'Your Fullname ' -to 'Her Fullname ' -subject 'My encrypted reply' |sendmail her@heraddress.com

How do I verify a signed S/MIME message?


It's pretty easy to verify a signed message.


openssl smime -verify -in msg.txt



If the sender's certificate isn't recognized by your OpenSSL
infrastructure, you'll get a verification error:


$ openssl smime -verify -in msg.txt
Verification failure
9544:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify
error:pk7_smime.c:222:Verify error:self signed certificate



The solution is to retrieve the sender's certificate or have it sent to you
directly and then tell openssl where it is.


openssl smime -verify -in msg.txt -CAfile /path/to/her-cert.pem

For further reading


Though it takes time to read them all and figure out how they relate to one
another, the 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), enc(1), gendsa(1), genrsa(1), nseq(1), ocsp(1),
openssl(1), passwd(1), pkcs12(1), pkcs7(1), pkcs8(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), verify(1), version(1), x509(1).


Comments welcome


Comments and suggestions about this document are appreciated and can be
addressed to the author at .


This article is licensed under a Creative Commons License.


Return to Technical Writings


Home - Tech - Praise - Paul - Books - About


(Embedded image moved to file: pic11025.gif)

0 Comments:

Post a Comment

<< Home