Chapter 2. Command-Line Interface

OpenSSL is primarily a library that is used by developers to include support for strong cryptography in their programs, but it is also a tool that provides access to much of its functionality from the command line. The command-line tool makes it easy to perform common operations, such as computing the MD5 hash of a file’s contents. What’s more, the command-line tool provides the ability to access much of OpenSSL’s higher-level functionality from shell scripts on Unix or batch files on Windows. It also provides a simple interface for languages that do not have native SSL bindings, but can run shell commands.

There’s no question that the command-line tool can seem quite complex to the uninitiated. It sports a large set of commands, and even larger sets of options that can be used to further refine and control those commands. OpenSSL does come with some documentation that covers most of the available commands and options supported by the command-line tool, but even that documentation can seem intimidating. Indeed, when you’re trying to discover the magical incantation to create a self-signed certificate, the documentation provided with OpenSSL does not provide an intuitive way to go about finding that information, even though it is in fact buried in there.

This chapter contains an overview of the command-line tool, providing some basic background information that will help make some sense of how the tool’s command structure is organized. We’ll also provide a high-level overview of how to accomplish many common tasks, including using message digests, symmetric ciphers, and public key cryptography. The Appendix contains a reference for the commands that the command-line tool supports.

We will refer to the command-line tool throughout this book, and, in some instances, we also provide examples that are more complex than what we’ve included in this chapter. In particular, Chapter 3 makes extensive use of the command-line tool.

The Basics

The command-line tool executable is aptly named openssl on Unix, and openssl.exe on Windows. It has two modes of operation: interactive and batch. When the program is started without any options, it will enter interactive mode. When operating in interactive mode, a prompt is displayed indicating that it is ready to process your command. After each command is completed, the prompt is redisplayed, and it’s once again ready to process another command. The program can be exited by simply issuing the quit command. Commands entered in interactive mode are handled in precisely the same manner as if you’d entered them from the command line in batch mode; the only difference is that you don’t need to type “openssl” before each command. We’ll normally operate the tool in batch mode in our examples, but if you feel more comfortable using the interactive mode, that’s fine.

The first part of a command is the name of the command itself. It’s followed by any options that you wish to specify, each one separated by a space. Options normally begin with a hyphen and often require a parameter of their own, in which case the parameter is placed after a space.

Unless indicated otherwise, the order in which you specify options is not significant. There are only a small number of cases in which the order is significant, usually because a specific option must appear on the command line as the last option specified.

Configuration Files

The command-line tool provides a large number of options for each of its many commands. Remembering the option names, their defaults if they’re not specified, and even to include them with a command to obtain the desired result can be difficult, if not downright frustrating at times. The task of managing options is made considerably simpler using configuration files.

OpenSSL includes a default configuration file that is normally used unless an alternate one is specified. The settings in the default configuration are all quite reasonable, but it can often be useful to replace them with settings that are better tailored to your own needs. The location of the default configuration file varies greatly, depending on the operating system that you’re using and how OpenSSL was built and installed. So, unfortunately, we can’t point you to any one specific location to find it. Although it is not at all intuitive, the command-line tool will tell you where the default configuration file is located if you issue the ca command without any options. Any errors that are issued due to the lack of options may be safely ignored.

Unfortunately, only three of the many commands supported by the command-line tool make any use of the configuration file. On the bright side, the three commands that do use it are perhaps the most complex of all of the supported commands, and accept the greatest number of options to control their behavior. The commands that do support the configuration file are ca, req, and x509 (we discuss these commands below).

An OpenSSL configuration file is organized in sections. Each section contains a set of keys, and each key has an associated value. Sections and keys are both named and case-sensitive. A configuration file is parsed from top to bottom with sections delimited by a line containing the name of the section surrounded by square brackets. The other lines contain key and value pairs that belong to the most recently parsed section delimiter. In addition, an optional global section that is unnamed occurs before the first named section in the file. Keys are separated from their associated value by an equals sign (=).

For the most part, whitespace is insignificant. Comments may begin anywhere on a line with a hash mark (#), and they end at the end of the line on which they begin. Key and section names may not contain whitespace, but they may be surrounded by it. Leading and trailing whitespace is stripped from a value, but any whitespace in the middle is significant. Example 2-1 shows an excerpt from the default OpenSSL configuration file.

Example 2-1. An excerpt from the default OpenSSL configuration file
[ ca ]
default_ca      = CA_default            # The default ca section
 
####################################################################
[ CA_default ]
 
dir             = ./demoCA              # Where everything is kept
certs           = $dir/certs            # Where the issued certs are kept
crl_dir         = $dir/crl              # Where the issued crl are kept
database        = $dir/index.txt        # database index file
new_certs_dir   = $dir/newcerts         # default place for new certs
 
certificate     = $dir/cacert.pem       # The CA certificate
serial          = $dir/serial           # The current serial number
crl             = $dir/crl.pem          # The current CRL
private_key     = $dir/private/cakey.pem# The private key
RANDFILE        = $dir/private/.rand    # private random number file
 
x509_extensions = usr_cert              # The extentions to add to the cert
 
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crl_extensions        = crl_ext
 
default_days    = 365                   # how long to certify for
default_crl_days= 30                    # how long before next CRL
default_md      = md5                   # which md to use
preserve        = no                    # keep passed DN ordering
 
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy          = policy_match

In the example, you’ll notice the use of $dir. Used in a value, a key name preceded by a dollar sign is known as a macro, and is replaced with the value for that key. Only macros using keys that are defined within the same section or in the global section will be expanded. Additionally, the key must be defined before you use it as a macro in a value, because the macro is expanded as the configuration file parses rather than when the value is used. Macros are particularly useful when you have a number of values referencing the same path in a filename.

Although only a few commands currently make any use of a configuration file, other commands may be modified in the future to take advantage of them. Each command that currently uses the configuration file reads its base configuration information from a section that shares the name of the command. Other sections that are not named after a command may exist, and quite frequently, they do. Many keys’ values are interpreted as the name of a section to use for finding more keys. We’ll see frequent examples of this as we examine the commands that do use the configuration file in detail.

Message Digest Algorithms

In Chapter 1, we introduced cryptographic hash functions, better known as message digest algorithms, which can be used for computing a checksum of a block of data. OpenSSL includes support for MD2, MD4, MD5, MDC2, SHA1 (sometimes called DSS1), and RIPEMD-160. SHA1 and RIPEMD-160 produce 160-bit hashes, and the others all produce 128-bit hashes. Unless you have a need for compatibility, we recommend that you use only SHA1 or RIPEMD-160. Both SHA1 and RIPEMD-160 provide excellent security for general-purpose use, but SHA1 is significantly more common. MD5 is a very popular message digest algorithm, but it does not have a good security margin for all applications. We discuss message digests in detail in Chapter 7.

OpenSSL handles SHA1 oddly. There are places where you must refer to it as DSS1 (the dgst command, described later), and there are places where you cannot refer to it as DSS1 (everywhere else). This is a limitation of the implementation. Use SHA1 as the name, unless we specifically mention that you need to use DSS1.

The command-line tool provides commands for using most of the supported algorithms. The dgst command is the main command for accessing message digests, but most of the algorithms can be accessed using a command of the same name as the algorithm. The exception is RIPEMD-160, which is named rmd160 .

When using the dgst command, the algorithm is specified using an option with the name of the algorithm, with the exception of RIPEMD-160, which also uses the name rmd160 for this interface. Regardless of the algorithm or form of the command, each of the algorithms accepts the same options to control how the command will function.

The default operation performed with any of the message digest commands is computing a hash for a block of data. That block of data can be read from stdin, or it can be one or more files. When more than one file is used, a separate hash is computed for each file. By default, the computed hash or hashes are written in hexadecimal format to stdout, unless an alternate output file is specified.

In addition to computing hashes, the message digest commands can also be used for signing and verifying signatures. When signing or verifying a signature, only one file should be used at a time; otherwise, the signatures will run together and end up being difficult to separate into a usable form. When signing, a signature is generated for the hash of the file to be signed. A private key is required to sign, and either RSA or DSA may be used. When you use a DSA private key, you must use the DSS1 message digest (even though it is the same as the SHA1 algorithm). You may use any algorithm other than DSS1 with an RSA private key. Verifying a signature is simply the reverse of signing. Normally, a public key is required to verify a signature, but a private key will work, too, because a public key can be derived from the private key, but not vice versa! When verifying a signature with an RSA key, public or private, you’ll also need to know which message digest algorithm was used to generate the signature.

Examples

The following examples illustrate the use of the message digest commands:

$ openssl dgst -sha1 file.txt

Computes an SHA1 hash for the file named file.txt and write it to stdout in hexadecimal form.

$ openssl sha1 -out digest.txt file.txt

Computes an SHA1 hash for the file named file.txt and write it in hexadecimal form to the file named digest.txt.

$ openssl dgst -dss1 -sign dsakey.pem -out dsasign.bin file.txt

Signs the SHA1 (DSS1) hash of the file named file.txt using the DSA private key in the file dsakey.pem and write the signature out to the file dsasign.bin. The PEM file format is a widely used format for storing cryptographic objects such as private keys, certificates, and so on. The “bin” extension indicates that the output is raw binary.

$ openssl dgst -dss1 -prverify dsakey.pem -signature dsasign.bin file.txt

Verifies the signature of the file named file.txt that is contained in the file dsasign.bin using the SHA1 (DSS1) message digest algorithm and the DSA private key from the file dsakey.pem.

$ openssl sha1 -sign rsaprivate.pem -out rsasign.bin file.txt

Signs the SHA1 hash of the file named file.txt using the RSA private key in the file rsaprivate.pem and write the signature out to the file rsasign.bin.

$ openssl sha1 -verify rsapublic.pem -signature rsasign.bin file.txt

Verifies the signature of the file named file.txt that is contained in the file rsasign.bin using the SHA1 message digest algorithm and the RSA public key from the file rsapublic.pem.

Symmetric Ciphers

OpenSSL supports a wide variety of symmetric ciphers. Of course, these ciphers are also available for use with the command-line tool. Many of the large number of ciphers are variations of a base cipher. The basic ciphers supported by the command-line tool are Blowfish, CAST5, DES, 3DES (Triple DES), IDEA, RC2, RC4, and RC5. Version 0.9.7 of OpenSSL adds support for AES. Most of the supported symmetric ciphers support a variety of different modes, including CBC, CFB, ECB, and OFB. For each cipher, the default mode is always CBC if a mode is not explicitly specified. Each of the supported symmetric ciphers and their various modes of operation are discussed in detail in Chapter 6. In particular, it is important to mention that you should generally never use ECB, because it is incredibly difficult to use securely.

The enc command is the main command for accessing symmetric ciphers, but each cipher can also be accessed using a command of the same name as the cipher. With the enc command, the cipher is specified using an option with the name of the cipher. Regardless of the cipher or form of the command that is used, each of the ciphers accepts the same options to control how the command will function. In addition to providing encryption and decryption of data with symmetric ciphers, the base64 command or option to the enc command can also be used for encoding and decoding of data in base64.

The default operation to be performed with any of the cipher commands is to encrypt or base64 encode the data. Normally, data is read from stdin and written to stdout, but input and output files may be specified. Only a single file can be encrypted, decrypted, base64 encoded, or base64 decoded at a time. When encrypting or decrypting, an option can be specified to perform base64 encoding after encryption or base64 decoding before decryption.

Each of the ciphers requires a key when encryption or decryption is performed. Recall from the brief discussion of symmetric ciphers in Chapter 1 that the key is what provides the security of a symmetric cipher. In contrast with traditional cryptographic techniques, modern cipher algorithms are widely available to be scrutinized by anyone that has the time and interest. The key used to encrypt data must be known only to you and the intended recipient or recipients of the encrypted data.

A password is often used to derive a key and initialization vector that will encrypt or decrypt the data. It is also possible to specify the key and initialization vector to be used explicitly, but supplying that information on your own is often prone to error. In addition, different ciphers have different key requirements, so supplying your own key requires in-depth knowledge of the particular cipher. The password can be specified with the pass option, according to the general guidelines for passwords and passphrases outlined later in this chapter. If no password or key information is specified, the tool will present a prompt to obtain it.

If you specify a password or passphrase to derive the key and initialization vector, the command-line tool uses a standard OpenSSL function to perform the task. Essentially, the password or passphrase that you specify is combined with a salt . The salt that is used in this case is simply eight random bytes. The MD5 hash of the combined salt and password or passphrase is then computed and broken into two parts, which are then used as the key and initialization vector.

Examples

The following examples illustrate the use of the symmetric cipher commands:

$ openssl enc -des3 -salt -in plaintext.doc -out ciphertext.bin

Encrypts the contents of the file plaintext.doc using DES3 in CBC mode and places the resulting ciphertext into ciphertext.bin. Since no password or key parameters were specified, a prompt for a password from which a key can be derived will be presented.

$ openssl enc -des3-ede-ofb -d -in ciphertext.bin -out plaintext.doc -pass pass:trousers

Decrypts the contents of the file ciphertext.bin using DES3 operating in OFB mode and places the resulting plaintext into plaintext.doc. The password “trousers” will be used to decrypt the file. Note that this example will not successfully decrypt the file from the previous example, since we used a different mode of encryption (CBC instead of OFB).

$ openssl bf-cfb -salt -in plaintext.doc -out ciphertext.bin -pass env:PASSWORD

Encrypts the contents of the file plaintext.doc using the Blowfish cipher in CFB mode and places the resulting ciphertext into ciphertext.bin. The contents of the environment variable PASSWORD will be used for the password to generate the key.

$ openssl base64 -in ciphertext.bin -out base64.txt

Encodes the contents of the file ciphertext.bin in base64 and writes the result to the file base64.txt.

$ openssl rc5 -in plaintext.doc -out ciphertext.bin -S C62CB1D49F158ADC -iv E9EDACA1BD7090C6 -K 89D4B1678D604FAA3DBFFD030A314B29

Encrypts the contents of the file plaintext.doc using the RC5 cipher in CBC mode and places the resulting ciphertext into ciphertext.bin. The specified salt, key, and initialization vector will be used to encrypt the plaintext. Keys are specified by their hexadecimal representation.

The Appendix gives a complete list of algorithms used to perform symmetric encryption.

Public Key Cryptography

The SSL protocol relies heavily on a variety of different cryptographic algorithms, including message digest algorithms, symmetric ciphers, and public key cryptography. Its use of most of these algorithms is generally done without the need for any human intervention. A common exception, though, is its use of public key cryptography. For example, in order for a server to employ the SSL protocol, it requires a private key and a certificate . The certificate contains the public key that matches the server’s private key. These keys must be created as part of the process for configuring the server to use SSL, and they are frequently not created automatically. Instead, they must be created by whoever is configuring the server.

SSL isn’t the only protocol that makes use of public key cryptography. Most modern software that supports encrypted communications uses it, too. Some of the more popular examples include SSH, PGP (Pretty Good Privacy), and S/MIME. All of these examples use public key cryptography in some form, and we’re overlooking many other applications as well. We discuss OpenSSL’s support for public key cryptography in detail in Chapter 8.

Diffie-Hellman

Diffie-Hellman is used for key agreement . In simple terms, key agreement is the exchange of information over an insecure medium that allows each of the two parties in a conversation to compute a value that is typically used as the key for a symmetric cipher. By itself, Diffie-Hellman cannot be used for encryption or authentication; it only provides secrecy. Because the exchange of information takes place over an insecure medium, it should never be used by itself. Some means of authenticating the parties in the conversation should also be used.

Diffie-Hellman works by first creating a set of parameters that are agreed upon by both parties in the conversation. The parameters, consisting of a randomly chosen prime number and a generator value that is typically specified as either 2 or 5, are public and can be either agreed upon before the conversation begins or exchanged as part of the conversation. Using the agreed-upon parameters, each party computes a public and private key. As its name implies, the private key is never shared with anyone. The parties exchange their public keys, and then each party can compute the shared secret using their private key and the peer’s public key.

The command-line tool provides a command for generating Diffie-Hellman parameters, but the only method for generating keys is deprecated, and should not be used. OpenSSL 0.9.5 added the dhparam command, and in doing so, deprecated the two commands dh and gendh, which were capable of generating Diffie-Hellman parameters and keys, respectively. As of this writing, the two deprecated commands are still accessible in OpenSSL 0.9.7, but because they’re deprecated, we’ll pretend that they do not exist, because they’re likely to be completely removed from the next release of OpenSSL. Unfortunately, the new dhparam command does not support the generation of Diffie-Hellman keys, but it is likely that future versions will add support for it.

Examples

The following examples illustrate the use of the Diffie-Hellman commands:

$ openssl dhparam -out dhparam.pem -2 1024

Generates a new set of Diffie-Hellman parameters using a generator of 2 and a random 1,024-bit prime, and writes the parameters in PEM format to the file dhparam.pem.

$ openssl dhparam -in dhparam.pem -noout -C

Reads a set of Diffie-Hellman parameters from the file dhparam.pem and writes a C code representation of the parameters to stdout.

Digital Signature Algorithm

As its name implies, the Digital Signature Algorithm (DSA) is used for creating and verifying digital signatures. It provides authentication, but cannot be used for encryption or secrecy. DSA is frequently used in combination with Diffie-Hellman. Two parties in a conversation can exchange DSA public keys before the conversation begins (or during the conversation using certificates, as we’ll explain in Chapter 3) and use the DSA keys to authenticate the communication of Diffie-Hellman parameters and keys. Combining Diffie-Hellman with DSA provides authentication and secrecy, and by using the shared secret resulting from the Diffie-Hellman exchange as a key, a symmetric cipher can then be used for encryption.

Just like Diffie-Hellman, DSA also requires parameters from which keys are generated. There is no harm in making the parameters used to generate a key pair public, but there’s equally no compelling reason to do so. Only the private key that is generated must be kept private, as is implied by its name. The public key is the only thing that really needs to be shared with any party that wishes to verify the authenticity of anything signed with a private key.

Three commands are provided by the command-line tool for generating DSA parameters and keys, as well as for examining and manipulating them. The dsaparam command is used to generate and examine DSA parameters. Its function and options are not unlike those of the dhparam command. One major difference between the two is that the dsaparam command also provides an option to generate a private DSA key. The private key resulting from the dsaparam command will be unencrypted, which means that neither a password nor a passphrase will be required to decrypt and make use of it.

The gendsa command is used for generating private keys from a set of DSA parameters. By default, the generated private key will not be encrypted, but options are available that allow the key to be encrypted using any one of the DES, 3DES, or IDEA ciphers. No options are provided for specifying the password or passphrase to use for encryption on the command line, so encrypted DSA private key generation cannot be easily automated.

Both the dsaparam and gendsa commands are capable of generating private keys, either encrypted or not, but neither of them has the capability for generating a public key, which is required in order for DSA to provide any utility. The dsa command provides the means by which a public key can be generated from a private key. It also allows changes to be made to the encryption on a private key. For private keys that are not encrypted, encryption can be added, and for private keys that are already encrypted, the password or passphrase can be changed, as well as the encryption cipher that’s used to encrypt it. It’s also possible to remove the encryption on a private key with this command.

Examples

The following examples illustrate the use of the DSA commands:

$ openssl dsaparam -out dsaparam.pem 1024

Generates a new set of DSA parameters and writes them to the file dsaparam.pem. The length of the prime and generator parameters will be 1,024 bits.

$ openssl gendsa -out dsaprivatekey.pem -des3 dsaparam.pem

Generates a new DSA private key using the parameters from the file dsaparam.pem, encrypts the newly generated private key with the 3DES cipher, and writes the result out to the file dsaprivatekey.pem.

$ openssl dsa -in dsaprivatekey.pem -pubout -out dsapublickey.pem

Computes the public key that corresponds to the private key contained in the file dsaprivatekey.pem and writes the public key out to the file dsapublickey.pem.

$ openssl dsa -in dsaprivatekey.pem -out dsaprivatekey.pem -des3 -passin
pass:oldpword -passout pass:newpword

Reads a private key from the file dsaprivatekey.pem, decrypts it using the password “oldpword”, re-encrypts it using the password “newpword”, and writes the newly encrypted private key back out to the file dsaprivatekey.pem.

RSA

RSA is the most popular public key algorithm currently in use, despite the fact that it was encumbered by patent restrictions until the patent expired in September of 2000. It is named after its creators, Ron Rivest, Adi Shamir, and Leonard Adleman. One of the reasons that it is so popular is because it provides secrecy, authentication, and encryption all in one neat little package.

Unlike Diffie-Hellman and DSA, the RSA algorithm does not require parameters to be generated before keys can be generated, which simplifies the amount of work that is necessary to generate keys, and authenticate and encrypt communications. The command-line tool provides three commands for generating, examining, manipulating, and using RSA keys.

OpenSSL’s genrsa command is used to generate a new RSA private key. Generation of an RSA private key involves finding two large prime numbers, each approximately half the length of the key. A typical key size for RSA is 1,024. We don’t recommend that you use smaller key lengths or key lengths greater than 2,048 bits. By default, the generated private key will be unencrypted, but the command does have the ability to encrypt the resultant key using DES, 3DES, or IDEA.

The rsa command is used to manipulate and examine RSA keys and is the RSA version of the dsa command for DSA keys. It is capable of adding, modifying, and removing the encryption protecting an RSA private key. It is also capable of producing an RSA public key from a private key. The command can also be used to display information about a public or private key.

The rsautl command provides the ability to use an RSA key pair for encryption and signatures. Options are provided for encrypting and decrypting data, as well as for signing and verifying signatures. Remember that signing is normally performed on hashes, so this command is not useful for signing large amounts of data, or even more than 160 bits of data. In general, we do not recommend that you use this command at all for signing data. You should use the enc command instead. Additionally, encryption and decryption using RSA is slow, and for that reason, it should not be used on its own. Instead, it is commonly used to encrypt a key for a symmetric cipher. This is discussed in more detail in Chapter 8.

Examples

The following examples illustrate the use of the RSA commands:

$ openssl genrsa -out rsaprivatekey.pem -passout pass:trousers -des3 1024

Generates a 1,024-bit RSA private key, encrypts it using 3DES and a password of “trousers”, and writes the result to the file rsaprivatekey.pem.

$ openssl rsa -in rsaprivatekey.pem -passin pass:trousers -pubout -out rsapublickey.pem

Reads an RSA private key from the file rsaprivatekey.pem, decrypts it using the password “trousers”, and writes the corresponding public key to the file rsapublickey.pem.

$ openssl rsautl -encrypt -pubin -inkey rsapublickey.pem -in plain.txt -out cipher.txt

Using the RSA public key from the file rsapublickey.pem, the contents of the file plain.txt are encrypted and written to the file cipher.txt.

$ openssl rsautl -decrypt -inkey rsaprivatekey.pem -in cipher.txt -out plain.txt

Using the RSA private key from the file rsaprivatekey.pem, the contents of the file cipher.txt are decrypted and written to the file plain.txt.

$ openssl rsautl -sign -inkey rsaprivatekey.pem -in plain.txt -out signature.bin

Using the RSA private key from the file rsaprivatekey.pem, the contents of the file plain.txt are signed, and the signature is written to the file signature.bin.

$ openssl rsautl -verify -pubin -inkey rsapublickey.pem -in signature.bin -out plain.txt

Using the RSA public key from the file rsapublickey.pem, the signature in the file signature.bin is verified, and the original unsigned data is written out to the file plain.txt.

S/MIME

S/MIME is a competing standard to PGP (Pretty Good Privacy) for the secure exchange of email. It provides authentication and encryption of email messages using public key cryptography, as does PGP. One of the primary differences in the two standards is that S/MIME uses a public key infrastructure to establish trust, whereas PGP does not. Trust is established when there is some means of proving that someone with a public key is actually that person, and that the key belongs to that person.

PGP was written and released in 1991 by Phil Zimmermann. It quickly became the de facto standard for the secure exchange of information throughout the world. Today, PGP has become an open standard known as OpenPGP, and is documented in RFC 2440. Because PGP does not rely on a public key infrastructure to establish trust, it is easy to set up and use. Today, one of the most common methods of establishing trust is obtaining someone’s public key either from a key server or directly from that person, and manually verifying the key’s fingerprint by comparing it with the fingerprint information obtained directly from the key’s owner over some trusted medium, such as the telephone or paper mail. It is also possible to sign a public key, so if Alice trusts Bob’s key, and Bob has used his key to sign Charlie’s key, Alice knows that she can trust Charlie’s key if the signature matches Bob’s. PGP works for small groups of people, but it does not scale well.

S/MIME stands for Secure Multipurpose Internet Mail Exchange. RSA Security developed the initial version in 1995 in cooperation with several other software companies; the IETF developed Version 3. Like PGP, S/MIME also provides encryption and authentication services. A public key infrastructure is used as a means of establishing trust, which means that S/MIME is capable of scaling to support large groups of people. The downside is that it requires the use of a public key infrastructure, which means that it is slightly more difficult to set up than PGP because a certificate must be obtained from a Certification Authority that is trusted by anyone using the certificate to encrypt or verify communications. Public keys are exchanged in the form of X.509 certificates, which require a Certification Authority to issue certificates that can be used. Because a Certification Authority is involved in the exchange of public keys, trust can be established if the certificate that issued a certificate is trusted. Public key infrastructure is discussed in detail in Chapter 3.

S/MIME messages may have multiple recipients. For an encrypted message, the body of the message is encrypted using a symmetric cipher, and the key for the symmetric cipher is encrypted using the recipient’s public key. When multiple recipients are involved, the same symmetric key is used, but the key is encrypted using each recipient’s public key. For example, if Alice sends the same message to Bob and Charlie, two encrypted copies of the key for the symmetric cipher are included in the message. One copy is encrypted using Bob’s public key, and the other is encrypted using Charlie’s public key. To decrypt a message, the recipient’s certificate is required to determine which encrypted key to decrypt.

The command-line tool provides the smime command, which supports encryption, decryption, signing, and verifying S/MIME v2 messages (support for S/MIME v3 is limited and is not likely to work). Email applications that do not natively support S/MIME can often be made to support it by using the command-line tool’s smime command to process incoming and outgoing messages. The smime command does have some limitations, and it is not recommended in any kind of production environment. However, it provides a good foundation for building a more powerful and fully featured S/MIME implementation.

Examples

The following examples illustrate the use of the S/MIME commands:

$ openssl smime -encrypt -in mail.txt -des3 -out mail.enc cert.pem

Obtains a public key from the X.509 certificate in the file cert.pem and encrypts the contents of the file mail.txt using that key and 3DES. The resulting encrypted S/MIME message is written to the file mail.enc.

$ openssl smime -decrypt -in mail.enc -recip cert.pem -inkey key.pem -out mail.txt

Obtains the recipient’s public key from the X.509 certificate in the file cert.pem and decrypts the S/MIME message from the file mail.enc using the private key from the file key.pem. The decrypted message is written to the file mail.txt.

$ openssl smime -sign -in mail.txt -signer cert.pem -inkey key.pem -out mail.sgn

The signer’s X.509 certificate is obtained from the file cert.pem, and the contents of the file mail.txt are signed using the private key from the file key.pem. The certificate is included in the S/MIME message that is written to the file mail.sgn.

$ openssl smime -verify -in mail.sgn -out mail.txt

Verifies the signature on the S/MIME message contained in the file mail.sgn and writes the result to the file mail.txt. The signer’s certificate is expected to be included as part of the S/MIME message.

Passwords and Passphrases

Many commands (particularly those that involve a private key) require a password or passphrase to complete successfully, usually to decrypt a key that is stored securely on a disk. Normally, the command-line tool will prompt you to enter a password or passphrase when appropriate, even if you’re not running the tool in interactive mode. The need for a password or passphrase to be physically entered by someone using the keyboard at the computer when it’s needed makes using the tool for automated processes difficult, to say the least.

Fortunately, there’s a solution. Many of the commands accept options that allow you to specify the necessary password or passphrase. Unfortunately, the options are not consistently named, so you need to use the right option with the right command. In general, the options passin and passout are used. No matter what the option is named, it requires a parameter that specifies how the password or passphrase will be obtained. A variety of sources may be specified, some of them not very secure at all. None of them provides the level of security that someone sitting at the computer and typing in the password or passphrase does, but you need to determine for yourself what you consider to be an acceptable risk.

stdin

This method for reading a password is distinctly different from the default method. The default method reads passwords from the actual terminal device (TTY), thus explicitly avoiding input redirection from the command line. The stdin method for providing passwords allows for such input redirection.

pass:<password>

This method can be used to supply the password or passphrase directly on the command line itself. If your password or passphrase contains spaces, you typically need to enclose the whole of the parameter in quotes, but the precise method of handling such a situation may differ on the platform that you’re using.

We strongly recommend that you do not use this method, for two reasons. First, if you’re using batch mode, the command line for a process is readily accessible to any other process that is running on the system. In fact, on such systems there are commands specifically designed for this purpose, such as the ps command on Unix systems. Second, if you’re using this as part of a script, it usually means the password or passphrase will be contained in your script, which also means that the password or passphrase can be easily compromised.

env:<variable>

This method obtains the password or passphrase from an environment variable. We recommend against using this method, although not as strongly as we do against specifying the password or passphrase directly on the command line. This method is slightly more secure, but a process’s environment is still available to other processes on some operating systems under the right circumstances.

file:<filename>

This method obtains the password or passphrase by reading it from the named file. The file containing the password or passphrase should be well protected, denying read access to any user on the system other than the owner of the file. Additionally, on Unix systems steps should be taken to ensure that each directory that parents the file does not allow access to a user other than the owner.

fd:<number>

This method obtains the password or passphrase by reading it from the specified file descriptor. This method is really useful only when the tool is launched from another process and not directly from the command line because the tool’s process must have inherited the file descriptor from its parent in order for it to gain access.

Seeding the Pseudorandom Number Generator

In Chapter 1, we briefly discussed the need for cryptographic randomness. We’ll expand on this discussion in Chapter 4. For now, we’ll just deal with how to seed the OpenSSL PRNG properly from the command line. Because many of the cryptographic commands depend on random numbers, it is important that the PRNG be seeded properly.

The command-line tool will attempt to seed the PRNG on its own, but it may not always be able to do so. When the PRNG is not properly seeded, the tool will emit a warning message indicating that the random numbers it generates will be predictable. Additionally, you may wish to use a more conservative seeding mechanism than the one used by default.

On Windows systems, a variety of sources will be used to seed the PRNG, including the contents of the screen. None of these sources is particularly entropic, and depending on the version of Windows that you’re using, the entropy sources vary. Unix systems that have a device named /dev/urandom will use that device to obtain entropy for seeding the PRNG. Most modern versions of Unix provide support for this device, which we’ll discuss in detail in Chapter 4. In addition, beginning with Version 0.9.7, OpenSSL will also attempt to seed the PRNG by connecting to an EGD socket to obtain entropy. By default, OpenSSL is built with four well-known names for sockets that it will attempt a connection with.

In addition to the base entropy sources, the command-line tool will also look for a file to obtain seed data from. If the RANDFILE environment variable is set, its value will be used as the name of the file to use for seeding the PRNG. If it is not set, a default filename of .rnd will be used, and the value of the HOME environment variable will be used to specify the location of that file. If the HOME environment variable is not set, as is often the case on non-Unix systems, the current directory will be used to find the file. Once the name of the file has been determined, the contents of that file will be loaded and used to seed the PRNG if it exists.

Many of OpenSSL’s commands require that its PRNG be properly seeded so that the random numbers it generates are unpredictable. In particular, any of the commands that generate key pairs always require unpredictable random numbers in order for them to be effective. When the tool is unable to seed the PRNG on its own, the tool provides an option named rand that can be used to provide additional entropy sources.

The rand option requires a parameter that contains a list of files to be used as entropy sources. The list may be as short as a single file, or as long as the number of filenames you can fit on the command line. Each file in the list is separated by a platform-dependent separator character rather than a space. The separator character is a semi-colon ( ;) on Windows, a comma (,) on OpenVMS, and a colon (:) on all other platforms. On Unix systems, each filename in the list is first checked to see if it is an Entropy Gathering Daemon (EGD) socket. If it is, entropy will be gathered from an EGD server; otherwise, seed data will be read from the contents of the named file.

EGD is an entropy-gathering daemon written in Perl that is intended for use in the absence of /dev/random or /dev/urandom. It is available from http://egd.sourceforge.net/ and runs on any Unix-based system that has Perl installed. It doesn’t work on Windows, but other entropy-gathering solutions are available for Windows. In particular, we recommend EGADS (Entropy Gathering And Distribution System), a C-based infrastructure that supports both Unix and Windows. This is a preferable solution even on Unix machines because it is far more conservative in its entropy collection and estimation. It is even a good solution on systems with a /dev/random. In such cases, it uses /dev/random as a single source of entropy. EGADS is available from http://www.securesw.com/egads/. It can be used anywhere an EGD socket is expected.

If Perl is installed on your system, EGD is easy to set up and run. Perl has become ubiquitous in the Unix world, so it’s unlikely that a modern system does not have it installed. Because EGD uses Perl, it’s very portable, even though it was originally written for Linux systems. On the other hand, EGD works by gathering its entropy from the output of running processes, a number of which produce a questionable amount of unpredictable data. Perhaps its biggest limitation is that it works only on Unix systems.

EGADS can be a bit more difficult to get up and running, but will usually compile straight from the distribution with a minimal amount of effort. On systems that do not have /dev/random, EGADS also gathers its entropy from the output of running processes. These processes are not as widely varied as EGD’s list. EGADS provides an EGD-compatible interface on Unix systems. Because EGADS provides an EGD interface and will use /dev/random to gather entropy, it provides a simplified interface for gathering entropy to clients such as those built with OpenSSL. It also supports Windows NT 4.0 and higher, which have no built-in entropy gathering services. It does not work on Windows 95, 98, or ME. Finally, EGADS also contains a cryptographically secure PRNG.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.221.120