OpenSSL命令简介

2010年5月3日 | 标签:

OpenSSL是一个使用广泛的开源工具。可以方便的做一些编码解码,md5/sha1摘要,aes/des加密解密,以及证书的生成及使用。

Linux操作系统一般都会自带openssl。

以下内容引自OpenSSL Command-Line HOWTO( http://www.madboa.com/geek/openssl/ )

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

Use the version option.

$ openssl version
OpenSSL 0.9.8b 04 May 2006

You can get much more information with the version -a option.

$ openssl version -a
OpenSSL 0.9.8b 04 May 2006
built on: Fri Sep 29 18:45:58 UTC 2006
platform: debian-i386-i686/cmov
options:  bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) blowfish(idx)
compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT
-DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO -O3 -march=i686
-Wa,--noexecstack -g -Wall -DOPENSSL_BN_ASM_PART_WORDS -DOPENSSL_IA32_SSE2
-DSHA1_ASM -DMD5_ASM -DRMD160_ASM -DAES_ASM
OPENSSLDIR: "/usr/lib/ssl"

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

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
-sha256 to use the sha256 message digest algorithm
-sha512 to use the sha512 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 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

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}

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

You can, in turn, pipe that information back to openssl to do things like check the dates on all your active certificates.

#!/bin/sh
#
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

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), /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.

  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

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:

openssl s_client -connect remote.host:25 -crlf -starttls smtp

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

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

How do I create an Apache digest password entry?

Apache’s HTTP digest authentication feature requires a special password format. Apache ships with the htdigest utility, but it will only write to a file, not to standard output. When working with remote users, it’s sometimes nice for them to be able to generate a password hash on a machine they trust and then mail it for inclusion in your local password database.

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

echo "Create an Apache-friendly Digest Password Entry"
echo "-----------------------------------------------"

# get user input, disabling tty echoing for password
read -p "Enter username: " UNAME
read -p "Enter Apache AuthName: " AUTHNAME
read -s -p "Enter password: " PWORD; echo

printf "\n%s:%s:%s\n" \
  "$UNAME" \
  "$AUTHNAME" \
  $(printf "${UNAME}:${AUTHNAME}:${PWORD}" | openssl dgst -md5)

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==

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

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

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.

# provide password on command line
openssl enc -aes-256-cbc -salt -in file.txt \
  -out file.enc -pass pass:mySillyPassword

# provide password in a file
openssl enc -aes-256-cbc -salt -in file.txt \
  -out file.enc -pass file:/path/to/secret/password.txt

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:

sshd[31784]: error: RSA_public_decrypt failed: error:0407006A:lib(4):func(112):reason(106)
sshd[770]: error: RSA_public_decrypt failed: error:0407006A:lib(4):func(112):reason(106)

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

# 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 create an elliptic curve key?

Routines for working with elliptic curve cryptography were added to OpenSSL in version 0.9.8. Generating an EC key involves the ecparam option.

openssl ecparam -out key.pem -name prime256v1 -genkey

# openssl can provide full list of EC parameter names suitable for
# passing to the -name option above:
openssl ecparam -list_curves

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.

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.

How do I test whether a number is prime?

Pass the number to the prime option. Note that the number returned by openssl will be in hex, not decimal, format.

$ openssl prime 119054759245460753
1A6F7AC39A53511 is not prime

You can also pass hex numbers directly.

$ openssl prime -hex 2f
2F is prime

How do I generate a set of prime numbers?

Pass a bunch of numbers to openssl and see what sticks. The seq utility is useful in this capacity.

# define start and ending points
AQUO=10000
ADQUEM=10100
for N in $(seq $AQUO $ADQUEM); do
  # use bc to convert hex to decimal
  openssl prime $N | awk '/is prime/ {print "ibase=16;"$1}' | bc
done

Random data

How do I generate random data?

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

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

# write 1024 bytes 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

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:

# get 32 bytes from /dev/urandom and base64 encode them
head -c 32 /dev/urandom | openssl enc -base64

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.

How do I verify a signed S/MIME message?

It’s pretty easy to verify a signed message. Use your mail client to save the signed message to a file. In this example, I assume that the file is named msg.txt.

openssl smime -verify -in msg.txt

If the sender’s certificate is signed by a certificate authority trusted by your OpenSSL infrastructure, you’ll see some mail headers, a copy of the message, and a concluding line that says Verification successful.

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

openssl smime -pk7out -in msg.txt | \
openssl pkcs7 -text -noout -print_certs

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.

openssl smime -pk7out -in msg.txt -out her-cert.pem

At that point, you can either integrate it into your OpenSSL infrastructure or you can save it off somewhere for special use.

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

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 her-cert.pem -encrypt -in my-message.txt

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 her-cert.pem -encrypt -des3 -in my-message.txt

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 <you@youraddress.com>' \
  -to 'Her Fullname <her@heraddress.com>' \
  -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 <you@youraddress.com>' \
  -to 'Her Fullname <her@heraddress.com>' \
  -subject 'My signed reply' |\
sendmail her@heraddress.com
下面是引自网上的翻译:
1、如何知道我的OpenSSL运行版本

QUOTE:

# openssl version
OpenSSL 0.9.7a Feb 19 2003

-a参数可以获得更详细的信息:

QUOTE:

# openssl version -a
OpenSSL 0.9.7a Feb 19 2003
built on: Tue Oct 31 02:10:29 EST 2006
platform: linux-elf
options:  bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) blowfish(idx)
compiler: gcc -fPIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -DOPENSSL_NO_ASM -DOPENSSL_NO_IDEA -DOPENSSL_NO_MDC2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_EC -I/usr/kerberos/include -DL_ENDIAN -DTERMIO -Wall -O2 -g -march=i386 -mcpu=i686 -Wa,–noexecstack
OPENSSLDIR: “/usr/share/ssl”
engines:  dynamic cswift chil atalla nuron ubsec aep ibmca sureware 4758cca

2、获取可用的命令列表
OpenSSL提供三个内置的选项命令组,而通过提供一个错误的参数,可以获得其帮助信息。(例如help、或-h)

QUOTE:

# openssl -h
openssl:Error: ‘-h’ 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

也可以获取某个命令组可用的参数:

QUOTE:

# 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

3、如何获取可用的密码(ciphers)列表

QUOTE:

# 显示所有可用的密码(ciphers)列表
openssl ciphers -v
# 仅显示TLSv1版本的密码
openssl ciphers -v -tls1
# 仅显示密钥大于128bit的高强度密码方式
openssl ciphers -v ‘HIGH’
# 仅显示使用AES运算法则的高强度密码方式
openssl ciphers -v ‘AES+HIGH’

三、性能测试
OpenSSL提供内置的性能测试组件,其通过speed选项,可以测试在一段时间内可以执行的操作数量,而不是测试固定数量操作的时间,这能确保即使是慢的系统,也不会花费过长的时间。
1、如何进行性能测试

QUOTE:

# 执行一个完整的性能测试
openssl speed
# 仅进行rsa的速度测试
openssl speed rsa
# 在一个SMP系统中,进行2路的rsa速度测试
openssl speed rsa -multi 2

2、如何测试远程连接的性能
使用s_time运行你测试远程连接的性能(30sec):

CODE:

openssl s_time -connect remote.host:443除了简单的测试外,s_time也允许进行指定的测试项目:

QUOTE:

# 使用新的session接收远程的test.html页面
openssl s_time -connect remote.host:443 -www /test.html -new
# 类似的,仅使用SSL v3版本和高强度的加密
openssl s_time \
  -connect remote.host:443 -www /test.html -new \
  -ssl3 -cipher HIGH
# 对比多个加密规则在10秒内连接的性能情况
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

如果你并没有SSL支持的Web服务器可以使用,你可以用s_server选项模拟:

QUOTE:

# 主机一,建立服务端(默认使用4433端口)
openssl s_server -cert mycert.pem -www
# 主机二,通过s_time连接到指定的4433端口进行测试
openssl s_time -connect myhost:4433 -www / -new -ssl3

[newpage]
四、证书
1、如何创建一个self-signed证书
首先,你需要决定是否使用短语(passphrase)加密你的密钥。一方面,使用短语加密密钥可以更安全,可以即使密钥被盗也不能使用;但另一方面,这意味着在启动web或ldap服务前,你需要把短语保存到文件上,或者手动的输入。先以一个没有短语的密钥为例。
下面的例子创建一个包含私钥和公钥的mycert.pem文件,该证书有效期为365日,而使用-nodes表示为不加密的密钥:

CODE:

openssl req \
  -x509 -nodes -days 365 \
  -newkey rsa:1024 -keyout mycert.pem -out mycert.pem
使用该命令,你将需要回答一连串的问题:Country Name, State, City等,特别是Common Name,是一个非常重要的区分信息。如果你的web服务器实际主机名是mybox.mydomain.com,而人们访问的是使用www.mydomain.com来访问,那么你应该使用www.mydomain.com来填写Common Name。
使用-subj参数,可以更方便的填写这些信息:

CODE:

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
2、如何创建一个给 VeriSign的证书
当为类似VeriSign的机构生成一个证书是比较复杂的官僚过程。在创建证书前,需要提交所有必须的文书文件。同上面一样,你必须考虑是否使用短语来加密你的密钥。下面都是假设你不使用这种方式。而得到一个叫mykey.pem的私钥文件,和myreq.pem的认证请求文件:

CODE:

openssl req \
  -new -newkey rsa:1024 -nodes \
  -keyout mykey.pem -out myreq.pem
如果你已经有私钥,而希望通过它生成认证请求文件,可以这样:

CODE:

openssl req -new -key mykey.pem -out myreq.pem类似的,你也可以一同在命令行中提交证书信息:

CODE:

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
当处理类似VeriSign的机构,你需要特别留意,所提交的信息资料都必须正确无误。即使在Organization Name中的“and”和“&”区别都会引起麻烦。当你提交证书请求前,应double check一次:

QUOTE:

# 校验签名
openssl req -in myreq.pem -noout -verify -key mykey.pem
# 检查信息
openssl req -in myreq.pem -noout -text

请把密钥文件存放在安全的地方。你需要它来使用VeriSign发给你的信息。然后,在VeriSign上提交证书请求即可。
3、我如何测试一个新的证书
使用s_server选项是最简单的测试方法。下面的例子假设你的密钥和证书都放在mycert.pem中。
首先,在测试端加载该证书,默认使用4433端口(可使用-accept选项修改):

CODE:

openssl s_server -cert mycert.pem -www如果加载顺利,那么,你使用浏览器访问https://yourserver:4433/,你应该可以看到一个使用不同密码和关于你连接状态信息的页面。而大部分的浏览器也允许你测试该正式的有效性。
4、我如何重新得到一个远程的证书
如果你懂openssl和sed,可以通过下面的脚本实现:

QUOTE:

#!/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’

5、如何从证书获得信息
一个SSL证书包括很多的信息,使用x509子命令,可以得到这些信息。下面的例子假设证书名称为:cert.pem。使用-text选项可以得到全部的信息:

CODE:

openssl x509 -text -in cert.pem使用不同的参数,可以获得指定的数据:

QUOTE:

# 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

6、如何导出或导入一个 PKCS#12证书
PKCS#12可以有一些如IIS等的应用程序导出或导入。它们通常使用.pfx的扩展文件名。
要创建一个PKCS#12证书,你需要一个私钥和证书。在下面的转换过程中,你有机会为证书输入一个“Export Password”(也可以留空):
# 创建一个包括密钥和自签名的证书文件

QUOTE:

openssl req \
  -x509 -nodes -days 365 \
  -newkey rsa:1024 -keyout mycert.pem -out mycert.pem
# 把mycert.pem导出为mycert.pfx的PKCS#12文件
openssl pkcs12 -export \
  -out mycert.pfx -in mycert.pem \
  -name “My Certificate”

如果有人发给你的是PKCS#12文件(含Export Password),你也可以export它为标准的PEM格式:
# 导出证书和短语密钥

CODE:

openssl pkcs12 -in mycert.pfx -out mycert.pem -nodes# 手动输入短语来导出证书

CODE:

openssl pkcs12 -in mycert.pfx -out mycert.pem五、确认证书
1、如何验证一个证书
使用verify选项即可:

CODE:

openssl verify cert.pem当验证通过,会显示OK信息:

QUOTE:

$ openssl verify remote.site.pem
remote.site.pem: OK

如果有错误,可得到简短的问题描述:

QUOTE:

error 10 at 0 depth lookup:certificate has expired.
证书已经过期。
error 18 at 0 depth lookup:self signed certificate.
除非有例外,否则,OpenSSL不会校验一个自签名的证书。

2、有哪些证书发行者是OpenSSL认可的
当在OpenSSL安装到系统中时,会配置一个“Directory for OpenSSL files”目录(编译时,通过–openssldir参数指定)。该目录存放有系统相信的证书发行者。可以使用下面的命令得到:(以红旗DC Server 5.0为例)

QUOTE:

$ openssl version -d
OPENSSLDIR: “/usr/share/ssl”

在certs的目录和子目录中,你发现一到三种类型的文件:
cert.pem 一个大文件,是像VerSign和Thawte的机构通过的证书;
在certs子目录,有些小文件,是CA的;
一些比较模糊的文件,有类似052eae11.0的文件名,并链接向.pem文件的。这些文件的第一部分实际上是基于指向.pem文件的hash值,而文件的扩展名意义不大,因为它理论上可以由不同的证书来创建咯。
例如在我的Gentoo系统,有个f73e89fd.0的文件,其指向vsignss.pem,就有:

QUOTE:

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

当一个程序处理一个远程的证书,它将检查cert.pem是否存在,不存在这创建hash值文件,存在,则校验该证书。
3、如何让OpenSSL任何和校验一个证书
把文件放到certs目录,并创建hash值文件,下面的脚本做到这一点:

QUOTE:

#!/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

六、客户端和服务端的命令
s_client和s_server选项提供一个方法执行SSL的客户端和服务端。
1、如何连接一个安全的SMTP服务端
你可以使用s_client选项来连接一个SSL SMTP服务端。安全的SMTP使用3个端口:25(TLS),465(SSL),587(TLS)。0.9.7版本后,openssl可以通过 -starttls来和smtp服务端通讯:

QUOTE:

# 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

大部分的邮件代理不区分<LF>或<CRLF>,但Qmail例外,所以,对于Qmail,可以这样:

CODE:

openssl s_client -connect remote.host:25 -crlf -starttls smtp2、如何连接其他安全服务端
连接到不同的,但均使用SSL的服务端是相同的:

QUOTE:

# 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

3、如何使用命令行建立一个 SSL server
s_server可以实现这个目的。但更好的办法,是使用Stunnel代替:

QUOTE:

# -www选项将返回一个HTML格式的页面给客户端
openssl s_server -cert mycert.pem -www
# -WWW选项模拟一个简单的web server,而使用当前目录的信息来返回给客户端。
# 在这个例子中,我们指定443端口代替默认的4433端口
openssl s_server -accept 443 -cert mycert.pem -WWW

七、dgst选项
1、如果创建一个文件的MD5或SHA1摘要
# MD5 digest
openssl dgst -md5 filename
# SHA1 digest
openssl dgst -sha1 filename
其结果和md5sum、sha1sum的结果是相同的。
2、签名
如果你希望使用digest,实现没有你的私钥而不能修改文件的目的。下面的例子使用SHA1实现:

QUOTE:

# 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

而foo-1.23.tar.gz.sha1 就是foo-1.23.tar.gz的签名信息公钥。
3、校验签名
要校验签名,需要有签名人的公钥:

QUOTE:

# 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

4、创建Apache digest password entry
Apache使用特殊的密码格式,而使用htdigest组件,仅输出到文件,而非标准输出。当对于远端用户,它比较方便用户在他们信任的机器上创建密码。下面的脚本模拟htdigest的输出,并显示到标准输出:

QUOTE:

#!/bin/bash

echo “Create an Apache-friendly Digest Password Entry”
echo “———————————————–”

# get user input, disabling tty echoing for password
read -p “Enter username: ” UNAME
read -p “Enter Apache AuthName: ” AUTHNAME
read -s -p “Enter password: ” PWORD; echo

printf “\n%s:%s:%s\n” \
  ”$UNAME” \
  ”$AUTHNAME” \
  $(printf “${UNAME}:${AUTHNAME}:${PWORD}” | openssl dgst -md5)

5、其他可以使用的digest类型
通过下面的命令可以得到所有的列表:

CODE:

openssl list-message-digest-commands[newpage]
七、加密和解密
1、使用base64编码

QUOTE:

# 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

命令行方式:

CODE:

$ echo "encode me" | openssl enc -base64
ZW5jb2RlIG1lCg==
※注意,echo默认会输出回车符,可使用-n参数屏蔽:

CODE:

$ echo -n "encode me" | openssl enc -base64
ZW5jb2RlIG1l
解密使用-d参数:

CODE:

$ echo "ZW5jb2RlIG1lCg==" | openssl enc -base64 -d
encode me
2、如何简单地加密一个文件
使用cipher是一种比较简单的加密方式,下面的命令可以知道其支持的运算规则:

CODE:

openssl list-cipher-commands当你选择号一个运算规则后,需要决定是否使用base64编码,以使用可打印字符来代替二进制方式的显示(例如要发送邮件),就可以这样做:

QUOTE:

# 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

解密时,提供短语和对应的规则即可:

QUOTE:

# 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

如果你连短语也不想手动输入,可以使用“PASS PHRASE ARGUMENTS”格式:

QUOTE:

# provide password on command line
openssl enc -aes-256-cbc -salt -in file.txt \
  -out file.enc -pass pass:mySillyPassword
# provide password in a file
openssl enc -aes-256-cbc -salt -in file.txt \
  -out file.enc -pass file:/path/to/secret/password.txt

八、错误
如果你从日志中发现一些SSL的内容错误信息,例如:
sshd[31784]: error: RSA_public_decrypt failed: error:0407006A:lib(4):func(112):reason(106)
sshd[770]: error: RSA_public_decrypt failed: error:0407006A:lib(4):func(112):reason(106)
你应该把error和lib之间的代码提取出来,并查询:
$ openssl errstr 0407006A
error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01
这样,再从manual里面去搜索信息,能比较好的解决问题。

九、密钥
1、如果创建一个RSA密钥
使用genrsa选项:

QUOTE:

# 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

2、如何创建一个RSA公钥
使用rsa选项,可以从私钥创建公钥:
openssl rsa -in mykey.pem -pubout
3、如果创建一个DSA密钥
创建DSA密钥需要parameter file,而且验证比RSA要慢,所以使用范围没有RSA广泛。
如果你想创建一个单一的RSA密钥,可以:

QUOTE:

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

另一方面,如果你希望多个DSA密钥共享一个parameter file,可以这样:

QUOTE:

# 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

4、创建elliptic curve key
OpenSSL 0.9.8以上的版本才支持elliptic curve key:

CODE:

openssl ecparam -out key.pem -name prime256v1 -genkey# -name 选型可以使用的参数,可通过下面的命令获得:

CODE:

openssl ecparam -list_curves5、如何从一个密钥移除passphrase(短语)
依赖于你使用rsa或dsa方式,使用不同的处理方法。
假设你创建的RSA密钥,并放在单独的key.pem文件,那么下面的命令后,你就可以得到一个没有短语加密,但相同编码的RSA密钥 newkey.pem

QUOTE:

# you’ll be prompted for your passphrase one last time
openssl rsa -in key.pem -out newkey.pem

通常,私钥和公钥可以放在同一个文件。假设叫mycert.pem。通过下面的步骤,也可以得到没有短语的文件newcert.pem

QUOTE:

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

[newpage]
十、Password hashes
使用passwd选项,你可以得到一个类似/etc/passwd或者/etc/shadow格式的密码。
1、创建一个crypt-style密码

QUOTE:

$ openssl passwd MySecret
8E4vqBR4UOYF

如果知道已经存在密码的“salt”,可以复制其hash:

QUOTE:

$ openssl passwd -salt 8E MySecret
8E4vqBR4UOYF.

否则,即使相同的密码,因每次的hash不同,结果也不同的。
2、创建一个shadow-style的密码
新的Unix系统(包括linux),都使用安全的MD5-based来作为salt,可以这样产生类似的密码:

QUOTE:

$ openssl passwd -1 MySecret
$1$HkrAilcM$Jy3vYQc8UiEXfTLRrlSpD.

而slat在二到三$符号之间,所以有:

QUOTE:

$ openssl passwd -1 -salt HkrAilcM MySecret
$1$HkrAilcM$Jy3vYQc8UiEXfTLRrlSpD.

十一、Prime numbers(素数)
从0.9.7e之后,prime选项被加入到openssl库中。
1、如何判断一个数字是否prime
使用prime选项即可。需要注意的是,返回的结果是十六进制,而非十进制形式的。

QUOTE:

$ openssl prime 119054759245460753
1A6F7AC39A53511 is not prime
$ openssl prime -hex 2f
2F is prime

2、如何创建一组prime numbers

QUOTE:

# define start and ending points
AQUO=10000
ADQUEM=10100
for N in $(seq $AQUO $ADQUEM); do
  # use bc to convert hex to decimal
  openssl prime $N | awk ‘/is prime/ {print “ibase=16;”$1}’ | bc
done

十二、随机数
使用rand选项可以得到二进制或base64编码后的随机数:

QUOTE:

# write 128 random bytes of base64-encoded data to stdout
openssl rand -base64 128
# write 1024 bytes 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

从 /dev/urandom可以得到类似的种子:

QUOTE:

# get 32 bytes from /dev/urandom and base64 encode them
head -c 32 /dev/urandom | openssl enc -base64

十三、S/MIME
S/MIME是发送和接收安全MIME的一个标准,常用于email中。通过OpenSSL的smime选项,可以提供命令行的S/MIME服务。
1、如何校验一个已经签名的S/MIME信息
把收到的信息保存到msg.txt文件即可:

CODE:

openssl smime -verify -in msg.txt如果发送人的证书被OpenSSL接受的,可以得到:

QUOTE:

Verification successful.

而如果内容被非认证架构修改,会得到错误信息:

QUOTE:

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:

而如果发送人的证书不在OpenSSL的识别范围内,也会出错:

QUOTE:

Verification failure
9544:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify
error:pk7_smime.c:222:Verify error:self signed certificate

大部分的邮件客户端,会随信息发送一个公共证书,从命令行也可以看到证书的信息:

CODE:

openssl smime -pk7out -in msg.txt | \
openssl pkcs7 -text -noout -print_certs
通过下面的命令,得到证书的copy

CODE:

openssl smime -pk7out -in msg.txt -out her-cert.pem这样,你就可以再次利用它来验证

CODE:

openssl smime -verify -in msg.txt -CAfile /path/to/her-cert.pem2、如何加密一个S/MIME信息
假设某人把她的公共证书发给你,并且要求你加密这些信息才给它。你应保存她的her-cert.pem文件。然后再reply。
为获得the default—though fairly weak—RC2-40 encryption,你应该告诉openssl信息和证书的位置

CODE:

openssl smime her-cert.pem -encrypt -in my-message.txt如果你确认对方有robust SSL toolkit,你可以指定一个类似DES的运算法则来加密

CODE:

openssl smime her-cert.pem -encrypt -des3 -in my-message.txt当使用sendmail时,可以一并来实现

CODE:

openssl smime her-cert.pem \
  -encrypt \
  -des3 \
  -in my-message.txt \
  -from 'Your Fullname <you@youraddress.com>' \
  -to 'Her Fullname <her@heraddress.com>' \
  -subject 'My encrypted reply' |\
sendmail her@heraddress.com
3、如何对S/MIME信息签名
如果你不想加密,而只是想签名,可以这样:

CODE:

openssl smime \
  -sign \
  -signer /path/to/your-cert.pem \
  -in my-message.txt \
  -from 'Your Fullname <you@youraddress.com>' \
  -to 'Her Fullname <her@heraddress.com>' \
  -subject 'My signed reply' |\
sendmail her@heraddress.com
唯一的区别,就是使用你自己的密钥和证书,而非发送者的证书咯。 1、如何知道我的OpenSSL运行版本

QUOTE:

# openssl version
OpenSSL 0.9.7a Feb 19 2003

-a参数可以获得更详细的信息:

QUOTE:

# openssl version -a
OpenSSL 0.9.7a Feb 19 2003
built on: Tue Oct 31 02:10:29 EST 2006
platform: linux-elf
options:  bn(64,32) md2(int) rc4(idx,int) des(ptr,risc1,16,long) blowfish(idx)
compiler: gcc -fPIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -DOPENSSL_NO_ASM -DOPENSSL_NO_IDEA -DOPENSSL_NO_MDC2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_EC -I/usr/kerberos/include -DL_ENDIAN -DTERMIO -Wall -O2 -g -march=i386 -mcpu=i686 -Wa,–noexecstack
OPENSSLDIR: “/usr/share/ssl”
engines:  dynamic cswift chil atalla nuron ubsec aep ibmca sureware 4758cca

2、获取可用的命令列表
OpenSSL提供三个内置的选项命令组,而通过提供一个错误的参数,可以获得其帮助信息。(例如help、或-h)

QUOTE:

# openssl -h
openssl:Error: ‘-h’ 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

也可以获取某个命令组可用的参数:

QUOTE:

# 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

3、如何获取可用的密码(ciphers)列表

QUOTE:

# 显示所有可用的密码(ciphers)列表
openssl ciphers -v
# 仅显示TLSv1版本的密码
openssl ciphers -v -tls1
# 仅显示密钥大于128bit的高强度密码方式
openssl ciphers -v ‘HIGH’
# 仅显示使用AES运算法则的高强度密码方式
openssl ciphers -v ‘AES+HIGH’

三、性能测试
OpenSSL提供内置的性能测试组件,其通过speed选项,可以测试在一段时间内可以执行的操作数量,而不是测试固定数量操作的时间,这能确保即使是慢的系统,也不会花费过长的时间。
1、如何进行性能测试

QUOTE:

# 执行一个完整的性能测试
openssl speed
# 仅进行rsa的速度测试
openssl speed rsa
# 在一个SMP系统中,进行2路的rsa速度测试
openssl speed rsa -multi 2

2、如何测试远程连接的性能
使用s_time运行你测试远程连接的性能(30sec):

CODE:

openssl s_time -connect remote.host:443除了简单的测试外,s_time也允许进行指定的测试项目:

QUOTE:

# 使用新的session接收远程的test.html页面
openssl s_time -connect remote.host:443 -www /test.html -new
# 类似的,仅使用SSL v3版本和高强度的加密
openssl s_time \
  -connect remote.host:443 -www /test.html -new \
  -ssl3 -cipher HIGH
# 对比多个加密规则在10秒内连接的性能情况
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

如果你并没有SSL支持的Web服务器可以使用,你可以用s_server选项模拟:

QUOTE:

# 主机一,建立服务端(默认使用4433端口)
openssl s_server -cert mycert.pem -www
# 主机二,通过s_time连接到指定的4433端口进行测试
openssl s_time -connect myhost:4433 -www / -new -ssl3

[newpage]
四、证书
1、如何创建一个self-signed证书
首先,你需要决定是否使用短语(passphrase)加密你的密钥。一方面,使用短语加密密钥可以更安全,可以即使密钥被盗也不能使用;但另一方面,这意味着在启动web或ldap服务前,你需要把短语保存到文件上,或者手动的输入。先以一个没有短语的密钥为例。
下面的例子创建一个包含私钥和公钥的mycert.pem文件,该证书有效期为365日,而使用-nodes表示为不加密的密钥:

CODE:

openssl req \
  -x509 -nodes -days 365 \
  -newkey rsa:1024 -keyout mycert.pem -out mycert.pem
使用该命令,你将需要回答一连串的问题:Country Name, State, City等,特别是Common Name,是一个非常重要的区分信息。如果你的web服务器实际主机名是mybox.mydomain.com,而人们访问的是使用www.mydomain.com来访问,那么你应该使用www.mydomain.com来填写Common Name。
使用-subj参数,可以更方便的填写这些信息:

CODE:

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
2、如何创建一个给 VeriSign的证书
当为类似VeriSign的机构生成一个证书是比较复杂的官僚过程。在创建证书前,需要提交所有必须的文书文件。同上面一样,你必须考虑是否使用短语来加密你的密钥。下面都是假设你不使用这种方式。而得到一个叫mykey.pem的私钥文件,和myreq.pem的认证请求文件:

CODE:

openssl req \
  -new -newkey rsa:1024 -nodes \
  -keyout mykey.pem -out myreq.pem
如果你已经有私钥,而希望通过它生成认证请求文件,可以这样:

CODE:

openssl req -new -key mykey.pem -out myreq.pem类似的,你也可以一同在命令行中提交证书信息:

CODE:

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
当处理类似VeriSign的机构,你需要特别留意,所提交的信息资料都必须正确无误。即使在Organization Name中的“and”和“&”区别都会引起麻烦。当你提交证书请求前,应double check一次:

QUOTE:

# 校验签名
openssl req -in myreq.pem -noout -verify -key mykey.pem
# 检查信息
openssl req -in myreq.pem -noout -text

请把密钥文件存放在安全的地方。你需要它来使用VeriSign发给你的信息。然后,在VeriSign上提交证书请求即可。
3、我如何测试一个新的证书
使用s_server选项是最简单的测试方法。下面的例子假设你的密钥和证书都放在mycert.pem中。
首先,在测试端加载该证书,默认使用4433端口(可使用-accept选项修改):

CODE:

openssl s_server -cert mycert.pem -www如果加载顺利,那么,你使用浏览器访问https://yourserver:4433/,你应该可以看到一个使用不同密码和关于你连接状态信息的页面。而大部分的浏览器也允许你测试该正式的有效性。
4、我如何重新得到一个远程的证书
如果你懂openssl和sed,可以通过下面的脚本实现:

QUOTE:

#!/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’

5、如何从证书获得信息
一个SSL证书包括很多的信息,使用x509子命令,可以得到这些信息。下面的例子假设证书名称为:cert.pem。使用-text选项可以得到全部的信息:

CODE:

openssl x509 -text -in cert.pem使用不同的参数,可以获得指定的数据:

QUOTE:

# 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

6、如何导出或导入一个 PKCS#12证书
PKCS#12可以有一些如IIS等的应用程序导出或导入。它们通常使用.pfx的扩展文件名。
要创建一个PKCS#12证书,你需要一个私钥和证书。在下面的转换过程中,你有机会为证书输入一个“Export Password”(也可以留空):
# 创建一个包括密钥和自签名的证书文件

QUOTE:

openssl req \
  -x509 -nodes -days 365 \
  -newkey rsa:1024 -keyout mycert.pem -out mycert.pem
# 把mycert.pem导出为mycert.pfx的PKCS#12文件
openssl pkcs12 -export \
  -out mycert.pfx -in mycert.pem \
  -name “My Certificate”

如果有人发给你的是PKCS#12文件(含Export Password),你也可以export它为标准的PEM格式:
# 导出证书和短语密钥

CODE:

openssl pkcs12 -in mycert.pfx -out mycert.pem -nodes# 手动输入短语来导出证书

CODE:

openssl pkcs12 -in mycert.pfx -out mycert.pem五、确认证书
1、如何验证一个证书
使用verify选项即可:

CODE:

openssl verify cert.pem当验证通过,会显示OK信息:

QUOTE:

$ openssl verify remote.site.pem
remote.site.pem: OK

如果有错误,可得到简短的问题描述:

QUOTE:

error 10 at 0 depth lookup:certificate has expired.
证书已经过期。
error 18 at 0 depth lookup:self signed certificate.
除非有例外,否则,OpenSSL不会校验一个自签名的证书。

2、有哪些证书发行者是OpenSSL认可的
当在OpenSSL安装到系统中时,会配置一个“Directory for OpenSSL files”目录(编译时,通过–openssldir参数指定)。该目录存放有系统相信的证书发行者。可以使用下面的命令得到:(以红旗DC Server 5.0为例)

QUOTE:

$ openssl version -d
OPENSSLDIR: “/usr/share/ssl”

在certs的目录和子目录中,你发现一到三种类型的文件:
cert.pem 一个大文件,是像VerSign和Thawte的机构通过的证书;
在certs子目录,有些小文件,是CA的;
一些比较模糊的文件,有类似052eae11.0的文件名,并链接向.pem文件的。这些文件的第一部分实际上是基于指向.pem文件的hash值,而文件的扩展名意义不大,因为它理论上可以由不同的证书来创建咯。
例如在我的Gentoo系统,有个f73e89fd.0的文件,其指向vsignss.pem,就有:

QUOTE:

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

当一个程序处理一个远程的证书,它将检查cert.pem是否存在,不存在这创建hash值文件,存在,则校验该证书。
3、如何让OpenSSL任何和校验一个证书
把文件放到certs目录,并创建hash值文件,下面的脚本做到这一点:

QUOTE:

#!/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

六、客户端和服务端的命令
s_client和s_server选项提供一个方法执行SSL的客户端和服务端。
1、如何连接一个安全的SMTP服务端
你可以使用s_client选项来连接一个SSL SMTP服务端。安全的SMTP使用3个端口:25(TLS),465(SSL),587(TLS)。0.9.7版本后,openssl可以通过 -starttls来和smtp服务端通讯:

QUOTE:

# 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

大部分的邮件代理不区分<LF>或<CRLF>,但Qmail例外,所以,对于Qmail,可以这样:

CODE:

openssl s_client -connect remote.host:25 -crlf -starttls smtp2、如何连接其他安全服务端
连接到不同的,但均使用SSL的服务端是相同的:

QUOTE:

# 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

3、如何使用命令行建立一个 SSL server
s_server可以实现这个目的。但更好的办法,是使用Stunnel代替:

QUOTE:

# -www选项将返回一个HTML格式的页面给客户端
openssl s_server -cert mycert.pem -www
# -WWW选项模拟一个简单的web server,而使用当前目录的信息来返回给客户端。
# 在这个例子中,我们指定443端口代替默认的4433端口
openssl s_server -accept 443 -cert mycert.pem -WWW

七、dgst选项
1、如果创建一个文件的MD5或SHA1摘要
# MD5 digest
openssl dgst -md5 filename
# SHA1 digest
openssl dgst -sha1 filename
其结果和md5sum、sha1sum的结果是相同的。
2、签名
如果你希望使用digest,实现没有你的私钥而不能修改文件的目的。下面的例子使用SHA1实现:

QUOTE:

# 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

而foo-1.23.tar.gz.sha1 就是foo-1.23.tar.gz的签名信息公钥。
3、校验签名
要校验签名,需要有签名人的公钥:

QUOTE:

# 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

4、创建Apache digest password entry
Apache使用特殊的密码格式,而使用htdigest组件,仅输出到文件,而非标准输出。当对于远端用户,它比较方便用户在他们信任的机器上创建密码。下面的脚本模拟htdigest的输出,并显示到标准输出:

QUOTE:

#!/bin/bash

echo “Create an Apache-friendly Digest Password Entry”
echo “———————————————–”

# get user input, disabling tty echoing for password
read -p “Enter username: ” UNAME
read -p “Enter Apache AuthName: ” AUTHNAME
read -s -p “Enter password: ” PWORD; echo

printf “\n%s:%s:%s\n” \
  ”$UNAME” \
  ”$AUTHNAME” \
  $(printf “${UNAME}:${AUTHNAME}:${PWORD}” | openssl dgst -md5)

5、其他可以使用的digest类型
通过下面的命令可以得到所有的列表:

CODE:

openssl list-message-digest-commands[newpage]
七、加密和解密
1、使用base64编码

QUOTE:

# 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

命令行方式:

CODE:

$ echo "encode me" | openssl enc -base64
ZW5jb2RlIG1lCg==
※注意,echo默认会输出回车符,可使用-n参数屏蔽:

CODE:

$ echo -n "encode me" | openssl enc -base64
ZW5jb2RlIG1l
解密使用-d参数:

CODE:

$ echo "ZW5jb2RlIG1lCg==" | openssl enc -base64 -d
encode me
2、如何简单地加密一个文件
使用cipher是一种比较简单的加密方式,下面的命令可以知道其支持的运算规则:

CODE:

openssl list-cipher-commands当你选择号一个运算规则后,需要决定是否使用base64编码,以使用可打印字符来代替二进制方式的显示(例如要发送邮件),就可以这样做:

QUOTE:

# 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

解密时,提供短语和对应的规则即可:

QUOTE:

# 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

如果你连短语也不想手动输入,可以使用“PASS PHRASE ARGUMENTS”格式:

QUOTE:

# provide password on command line
openssl enc -aes-256-cbc -salt -in file.txt \
  -out file.enc -pass pass:mySillyPassword
# provide password in a file
openssl enc -aes-256-cbc -salt -in file.txt \
  -out file.enc -pass file:/path/to/secret/password.txt

八、错误
如果你从日志中发现一些SSL的内容错误信息,例如:
sshd[31784]: error: RSA_public_decrypt failed: error:0407006A:lib(4):func(112):reason(106)
sshd[770]: error: RSA_public_decrypt failed: error:0407006A:lib(4):func(112):reason(106)
你应该把error和lib之间的代码提取出来,并查询:
$ openssl errstr 0407006A
error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01
这样,再从manual里面去搜索信息,能比较好的解决问题。

九、密钥
1、如果创建一个RSA密钥
使用genrsa选项:

QUOTE:

# 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

2、如何创建一个RSA公钥
使用rsa选项,可以从私钥创建公钥:
openssl rsa -in mykey.pem -pubout
3、如果创建一个DSA密钥
创建DSA密钥需要parameter file,而且验证比RSA要慢,所以使用范围没有RSA广泛。
如果你想创建一个单一的RSA密钥,可以:

QUOTE:

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

另一方面,如果你希望多个DSA密钥共享一个parameter file,可以这样:

QUOTE:

# 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

4、创建elliptic curve key
OpenSSL 0.9.8以上的版本才支持elliptic curve key:

CODE:

openssl ecparam -out key.pem -name prime256v1 -genkey# -name 选型可以使用的参数,可通过下面的命令获得:

CODE:

openssl ecparam -list_curves5、如何从一个密钥移除passphrase(短语)
依赖于你使用rsa或dsa方式,使用不同的处理方法。
假设你创建的RSA密钥,并放在单独的key.pem文件,那么下面的命令后,你就可以得到一个没有短语加密,但相同编码的RSA密钥 newkey.pem

QUOTE:

# you’ll be prompted for your passphrase one last time
openssl rsa -in key.pem -out newkey.pem

通常,私钥和公钥可以放在同一个文件。假设叫mycert.pem。通过下面的步骤,也可以得到没有短语的文件newcert.pem

QUOTE:

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

[newpage]
十、Password hashes
使用passwd选项,你可以得到一个类似/etc/passwd或者/etc/shadow格式的密码。
1、创建一个crypt-style密码

QUOTE:

$ openssl passwd MySecret
8E4vqBR4UOYF

如果知道已经存在密码的“salt”,可以复制其hash:

QUOTE:

$ openssl passwd -salt 8E MySecret
8E4vqBR4UOYF.

否则,即使相同的密码,因每次的hash不同,结果也不同的。
2、创建一个shadow-style的密码
新的Unix系统(包括linux),都使用安全的MD5-based来作为salt,可以这样产生类似的密码:

QUOTE:

$ openssl passwd -1 MySecret
$1$HkrAilcM$Jy3vYQc8UiEXfTLRrlSpD.

而slat在二到三$符号之间,所以有:

QUOTE:

$ openssl passwd -1 -salt HkrAilcM MySecret
$1$HkrAilcM$Jy3vYQc8UiEXfTLRrlSpD.

十一、Prime numbers(素数)
从0.9.7e之后,prime选项被加入到openssl库中。
1、如何判断一个数字是否prime
使用prime选项即可。需要注意的是,返回的结果是十六进制,而非十进制形式的。

QUOTE:

$ openssl prime 119054759245460753
1A6F7AC39A53511 is not prime
$ openssl prime -hex 2f
2F is prime

2、如何创建一组prime numbers

QUOTE:

# define start and ending points
AQUO=10000
ADQUEM=10100
for N in $(seq $AQUO $ADQUEM); do
  # use bc to convert hex to decimal
  openssl prime $N | awk ‘/is prime/ {print “ibase=16;”$1}’ | bc
done

十二、随机数
使用rand选项可以得到二进制或base64编码后的随机数:

QUOTE:

# write 128 random bytes of base64-encoded data to stdout
openssl rand -base64 128
# write 1024 bytes 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

从 /dev/urandom可以得到类似的种子:

QUOTE:

# get 32 bytes from /dev/urandom and base64 encode them
head -c 32 /dev/urandom | openssl enc -base64

十三、S/MIME
S/MIME是发送和接收安全MIME的一个标准,常用于email中。通过OpenSSL的smime选项,可以提供命令行的S/MIME服务。
1、如何校验一个已经签名的S/MIME信息
把收到的信息保存到msg.txt文件即可:

CODE:

openssl smime -verify -in msg.txt如果发送人的证书被OpenSSL接受的,可以得到:

QUOTE:

Verification successful.

而如果内容被非认证架构修改,会得到错误信息:

QUOTE:

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:

而如果发送人的证书不在OpenSSL的识别范围内,也会出错:

QUOTE:

Verification failure
9544:error:21075075:PKCS7 routines:PKCS7_verify:certificate verify
error:pk7_smime.c:222:Verify error:self signed certificate

大部分的邮件客户端,会随信息发送一个公共证书,从命令行也可以看到证书的信息:

CODE:

openssl smime -pk7out -in msg.txt | \
openssl pkcs7 -text -noout -print_certs
通过下面的命令,得到证书的copy

CODE:

openssl smime -pk7out -in msg.txt -out her-cert.pem这样,你就可以再次利用它来验证

CODE:

openssl smime -verify -in msg.txt -CAfile /path/to/her-cert.pem2、如何加密一个S/MIME信息
假设某人把她的公共证书发给你,并且要求你加密这些信息才给它。你应保存她的her-cert.pem文件。然后再reply。
为获得the default—though fairly weak—RC2-40 encryption,你应该告诉openssl信息和证书的位置

CODE:

openssl smime her-cert.pem -encrypt -in my-message.txt如果你确认对方有robust SSL toolkit,你可以指定一个类似DES的运算法则来加密

CODE:

openssl smime her-cert.pem -encrypt -des3 -in my-message.txt当使用sendmail时,可以一并来实现

CODE:

openssl smime her-cert.pem \
  -encrypt \
  -des3 \
  -in my-message.txt \
  -from 'Your Fullname <you@youraddress.com>' \
  -to 'Her Fullname <her@heraddress.com>' \
  -subject 'My encrypted reply' |\
sendmail her@heraddress.com
3、如何对S/MIME信息签名
如果你不想加密,而只是想签名,可以这样:

CODE:

openssl smime \
  -sign \
  -signer /path/to/your-cert.pem \
  -in my-message.txt \
  -from 'Your Fullname <you@youraddress.com>' \
  -to 'Her Fullname <her@heraddress.com>' \
  -subject 'My signed reply' |\
sendmail her@heraddress.com
唯一的区别,就是使用你自己的密钥和证书,而非发送者的证书咯。

相关文章:

  1. 一些典型场景的Postfix配置说明
  2. “Too many open files” – 合理配置Linux同时可打开文件句柄数限制及lsof命令使用
  3. openvz网络配置
  4. 如何转换物理机或虚拟机为OpenVZ Containers
  5. CentOS 5.4 Xen 3.4.2安装/升级
目前还没有任何评论.