6.2. Creating an Identity
Most
SSH implementations include a program for creating key pairs. We will
cover
ssh-keygen from
SSH1, SSH2, and OpenSSH.
6.2.1. Generating RSA Keys for SSH1
SSH1 and its derivatives use the program
ssh-keygen1
to create key pairs. [
Section 2.4.2, "Generating Key Pairs with ssh-keygen"] The program might
also be called
ssh-keygen, depending on how SSH1
was installed. Let's go into more detail about this program
than we have before.
Appendix B, "SSH Quick Reference" summarizes the
ssh-keygen options.
ssh-keygen1 can create new keys or modify existing
keys. When creating a new key, you may indicate the following with
command-line
options:
- The number of bits in the key, using
-b. The default is 1024 bits.
$ ssh-keygen1 -b 2048
- The name of the private key file to be generated, using
-f. The name is relative to your current directory.
Recall that the public key file is named after the private one with
.pub appended. If you omit this option, you are
prompted for the information.
$ ssh-keygen1 -f mykey Creates
mykey and mykey.pub
$ ssh-keygen1
Enter file in which to save the key (/home/barrett/.ssh/identity): mykey
- The
passphrase
to decode the key, using -N. If you omit this
option, you'll be prompted after generation.
$ ssh-keygen1 -N secretword
$ ssh-keygen1
Enter passphrase: [nothing is echoed]
Enter the same passphrase again: [nothing is echoed]
- A textual comment
associated with the key, using -C. If you omit this
option, the comment will be "username@host", where
username is your username on the local machine and host is the fully
qualified domain name of the local machine:
$ ssh-keygen1 -C "my favorite key"
If you specify both
-f (specify output file) and
-N (specify password),
ssh-keygen1 issues no prompts. Therefore, you can
automate key generation using these options (and perhaps redirecting
output to
/dev/null ) :
$ ssh-keygen1 -f mykey -N secretword
You might use this technique to automate generation of a large number
of keys for some purpose. Use it carefully, though, on a secure
machine. The password on the command line is probably visible to
other users on the same Unix machine via
ps or
similar programs, and if you're scripting with this technique,
obviously the passphrases shouldn't be kept in files for long.
In addition to creating keys,
ssh-keygen1 can
modify existing keys in the following ways:
- By changing the
passphrase
of an existing key, using -p. You can specify the
filename with -f and the old and new passphrases
with -P and -N, respectively:
$ ssh-keygen1 -p -f mykey -P secretword -N newword
but if you omit them, you are prompted:
$ ssh-keygen1 -p
Enter file key is in (/home/barrett/.ssh/identity): mykey
Enter old passphrase: [nothing is echoed]
Key has comment 'my favorite key'
Enter new passphrase: [nothing is echoed]
Enter the same passphrase again:
Note that this changes the passphrase but doesn't change the
key, it just re-encrypts the key with the new passphrase. So, the
corresponding public key file doesn't change or need to be
replaced on the SSH server machines to which you've copied
it.
WARNING:
Before using any option that places your passphrase on the shell
command line, such as -N or -P,
carefully consider the security implications. Because the passphrase
appears on your screen, it may be visible to onlookers, and while
running, it may be visible in the machine's process list.
Because it is on the command line, it is visible to other users on
the same host using the ps command. In addition,
if your shell creates history files of the commands you type, the
passphrase is inserted into a history file where it can be read by a
third party.
Also, if you think have
a good reason to just type Return
and give your key no passphrase, think again. Doing that is
essentially equivalent to putting your password in a file in your
home directory named
MY-PASSWORD.PLEASE-STEAL-ME. If you don't
want to have to type a passphrase, the right thing to do is to use
ssh-agent, trusted-host authentication, or
Kerberos. There are very limited circumstances having to do with
unattended usage (e.g., cron jobs) where a
plaintext, passphrase-less client key might be acceptable. [Section 11.1, "Unattended SSH: Batch or cron Jobs"]
- By changing the comment of
an existing key, using -c. You may specify the
filename, passphrase, and new comment with -f,
-P, and -C, respectively,
or you are prompted for them:
$ ssh-keygen -c -f mykey -P secretword -C "my second-favorite key"
$ ssh-keygen -c
Enter file key is in (/home/barrett/.ssh/identity): mykey
Enter passphrase: [nothing is echoed]
Key now has comment 'my favorite key'
Enter new comment: my second-favorite key
The comment in your key file has been changed.
- By upgrading an old
SSH1 key to work with the current version of SSH1, with
-u. Older versions of SSH1 used the IDEA
algorithm to encrypt a key with its passphrase, but nowadays SSH1
uses 3DES for this purpose, rendering these older keys unusable. The
-u option causes ssh-keygen1
to decrypt the key and reencrypt it with SSH1's default
algorithm (normally 3DES) to use with the current version of SSH1:
$ ssh-keygen1 -u -f mykey -P secretword
$ ssh-keygen1 -u
Enter file key is in (/home/barrett/.ssh/identity): mykey
Enter passphrase: [nothing is echoed]
Key's cipher has been updated.
When you make changes to a key, such as its passphrase or comment,
the changes are applied to the key file only. If you have keys loaded
into an SSH agent, the copies in the agents aren't changed. For
instance, if you list the keys in the agent with
ssh-add1 -l
(lowercase L) after changing the comment, you still see the
old comment in the agent. To make the changes take effect in the
agent, unload and reload the affected keys.
6.2.2. Generating RSA/DSA Keys for SSH2
SSH2 and
its derivatives use the cleverly named program
ssh-keygen2
to create key pairs. The program might also be called
ssh-keygen, depending on how SSH2 was installed.
As with
ssh-keygen1, you can create new keys or
modify existing ones; however, the command-line options are
significantly different.
ssh-keygen2 also has a
few other options for printing diagnostics.
When creating a new key, you may choose the name of the private key
file to be generated, by specifying the name at the end of the
command line:
$ ssh-keygen2 mykey creates mykey and mykey.pub
The name is relative to your current directory, and as usual, the
public key file is named after the private one with
.pub
appended. If you omit this option, the key is saved in the directory
~/.ssh2, in a file whose name indicates the
encryption algorithm and number of bits. An example is
id_dsa_1024_a, which was generated by the DSA
algorithm with 1024 bits.
You also may indicate the following with command-line options:
- The number of bits in the key, using
-b. The default is 1024 bits.
$ ssh-keygen2 -b 2048
- The key type, such as DSA or
RSA, using -t. The default -- and only
option -- for SSH2 is DSA (given as "dsa"):[79]
$ ssh-keygen2 -t dsa
- A textual comment
associated with the key, using -c:
$ ssh-keygen2 -c "my favorite SSH2 key"
- If you omit this option, the generated comment describes how and by
whom the key was generated. For example:
"1024-bit dsa, barrett@server.example.com, Tue Feb 22 2000 02:03:36"
- The
passphrase
to decode the key, using -p. If you omit this
option, you are prompted after generation.
$ ssh-keygen2 -p secretword
You can also designate an empty password using
-P. This shouldn't be done in general but
is appropriate in some special cases. [Section 11.1.2.2, "Using a plaintext key"]
$ ssh-keygen2 -P
In addition to creating keys,
ssh-keygen2 can
operate on existing keys in the following ways:
- By changing the
passphrase
and comment of
an existing key, using -e. This option causes
ssh-keygen2 to become interactive, prompting for
the new information. This interactive mode is primitive and annoying,
requiring nearly 10 user responses to change the passphrase and
comment, but it does the job:
$ ssh-keygen2 -e mykey
Passphrase needed for key "my favorite SSH2 key"
Passphrase : [nothing is echoed]
Do you want to edit key "my favorite SSH2 key" (yes or no)? yes
Your key comment is "my favorite SSH2 key".
Do you want to edit it (yes or no)? yes
New key comment: this is tedious
Do you want to edit passphrase (yes or no)? yes
New passphrase : [nothing is echoed]
Again : [nothing is echoed]
Do you want to continue editing key "this is tedious" (yes or no)? god no
(yes or no)? no
Do you want to save key "this is tedious" to file mykey (yes or no)? yes
As with ssh-keygen1, changes are applied to the
key files but not propagated to the copies currently loaded in an
agent. (So if you do an ssh-add2 -l to list the
keys, for example, you see the old comment.)
- By printing the public key, deriving it from the private
key, with -D, in case you ever lose your private
key file:
$ ssh-keygen2 -D mykeyfile
Passphrase : ********
Public key saved to mykeyfile.pub
- By converting an
SSH-1 format key to SSH-2 format, using -1
(that's the digit "one", not a lowercase L). This
isn't currently implemented.
$ ssh-keygen2 -1 ssh1key
ssh-keygen2 also gives you some control over
input, output and diagnostics:
- By printing the
fingerprint
of a given key file, with -F. See the sidebar "Key Fingerprints" for more information. The
fingerprint can be calculated from the public key:
# SSH2 only
$ ssh-keygen2 -F stevekey.pub
Fingerprint for key:
xitot-larit-gumet-fyfim-sozev-vyned-cigeb-sariv-tekuk-badus-bexax
- By printing the program version number, with
-V:
$ ssh-keygen2 -V
ssh2: SSH Secure Shell 2.1.0 (noncommercial version)
- By printing a help message, with -h or
-?. Most Unix shells require you to escape the
question mark, to prevent the shell from interpreting it as a
wildcard.
$ ssh-keygen2 -h
$ ssh-keygen2 -\? Escaping the question mark
- By suppressing the progress indicator, using
-q. The progress indicator is a sequence of
O's and periods that displays while
ssh-keygen2 runs, like this:
.oOo.oOo.oOo.oOo.
$ ssh-keygen2
Generating 1024-bit dsa key pair
.oOo.oOo.oOo.oOo
Key generated.
$ ssh-keygen2 -q
Generating 1024-bit dsa key pair
Key generated.
- By displaying information about an existing key, using
-i:
$ ssh-keygen2 -i mykey
This isn't currently implemented.
Finally,
ssh-keygen2 has one guru-level advanced
option,
-r, for affecting the random numbers
used for key generation. It causes
ssh-keygen2 to
modify
~/.ssh2/random_seed using data you enter on standard input.
[
Section 3.7, "Randomness"] The SSH2 manpages call this
"
stirring data into the random
pool." Note that the program doesn't prompt you to enter
data; it just sits there looking like it's hung. When this
occurs, type as much data as you like and press the EOF character
(
Control-D in most shells).
$ ssh-keygen2 -r
I am stirring the random pool.
blah blah blah
^D
Stirred in 46 bytes.
6.2.3. Generating RSA/DSA Keys for OpenSSH
OpenSSH's
ssh-keygen program supports all the same features
and options of its SSH1 counterpart. It also adds the capability to
generate DSA keys for SSH-2 connections and a few more options:
- -d generates a DSA key
instead of an RSA key:
# OpenSSH only
$ ssh-keygen -d
- -x, -X, and -y
convert between SSH2 and OpenSSH
key-storage formats. The following table illustrates this:
Option |
Extract/Convert from... |
To... |
-x |
OpenSSH DSA private key file |
SSH2 public key |
-X |
SSH2 public key file |
OpenSSH DSA public key |
-y |
OpenSSH DSA private key file |
OpenSSH DSA public key |
An OpenSSH "private" key file actually contains both the
public and private keys of a pair, so the -x and
-y options simply extract the public key and print
it out in the desired format. Use -x to add an
OpenSSH public key to your ~/.ssh2/authorization
file on an SSH2 server host and -X to do the
opposite. The -y option is useful if you
accidentally delete your OpenSSH public key file and need to restore
it.
A function that's missing is converting the
private keys as well. This is useful if you have
an OpenSSH server host on which you also want to also run SSH2, and
you want the two SSH servers to share a host key.
- -l prints the
fingerprint of a given key
file. See the sidebar "Key Fingerprints" for more
information. The fingerprint can be calculated from the public
key:
# OpenSSH only
$ ssh-keygen -l -f stevekey.pub
1024 5c:f6:e2:15:39:14:1a:8b:4c:93:44:57:6b:c6:f4:17 steve@sshbook.com
Key Fingerprints
Fingerprints
are a common cryptographic feature for checking that two keys in
different places are the same, when comparing them
literally -- bit by bit -- is infeasible. OpenSSH and SSH2 can
compute fingerprints.
Suppose Steve wants SSH access to Judy's account. He sends his
public key to Judy by email, and she installs it in her SSH
authorization file. While this key exchange seems straightforward, it
is insecure: a hostile third party could intercept Steve's key
and substitute his own, gaining access to Judy's account.
To prevent this risk, Judy needs some way to verify that the key she
receives is Steve's. She could call Steve on the telephone and
check, but reading a 500-byte encrypted public key over the phone is
annoying and error-prone. This is why fingerprints exist.
A fingerprint is a short value computed from a key. It's
analogous to a checksum, verifying that a string of data is
unaltered -- in our case, a key. To check the validity of a key
using fingerprints, Steve and Judy can do the following:
- Judy receives a public key that is supposed to be Steve's,
storing it in the file stevekey.pub.
- Separately, Judy and Steve view the fingerprint of the
key:
# OpenSSH only
$ ssh-add -l stevekey.pub
1024 5c:f6:e2:15:39:14:1a:8b:4c:93:44:57:6b:c6:f4:17 Steve@sshbook.com
# SSH2 only
$ ssh-keygen2 -F stevekey.pub
Fingerprint for key:
xitot-larit-gumet-fyfim-sozev-vyned-cigeb-sariv-tekuk-badus-bexax
- Judy calls Steve on the telephone and asks him to read the
fingerprint over the phone. Judy verifies that it matches the
fingerprint of the key she received. Fingerprints aren't
unique, but for any two keys, the probability that their fingerprints
are identical is small. Therefore, keys are a quick and convenient
method for checking that a key is
unaltered.
As you can see, OpenSSH and SSH2 use different output formats for
fingerprints. OpenSSH's numeric format is more traditional and
should be familiar to users of PGP. SSH2 uses a textual format called
"Bubble Babble" which is claimed to be easier to read and
remember.
Fingerprints also surface when you connect to an SSH server whose
host key has changed. In this case, OpenSSH prints a warning message
and the fingerprint of the new key, which may be conveniently
compared with the fingerprint of the real host key, should you have
it.
|
- -R detects whether OpenSSH supports RSA
keys or not. Because RSA was
patented technology until September 2000, a particular installation
of OpenSSH may or may not include this algorithm. [Section 3.9.1.1, "Rivest-Shamir-Adleman (RSA)"] If you invoke ssh-keygen
with this option, it immediately exits with a code of
0 if RSA is supported, or 1 if
it isn't.
# OpenSSH only, with RSA support
$ ssh-keygen -R; echo $?
0
# OpenSSH only, without RSA support
$ ssh-keygen -R; echo $?
1
6.2.4. Selecting a Passphrase
Choose your
passphrases
carefully. Make them at least 10 characters long, containing a mix of
uppercase and lowercase letters, digits, and nonalphanumeric symbols.
At the same time, you want the passphrase to be easy to remember, but
hard for others to guess. Don't use your name, username, phone
number, or other easily guessed information in the passphrase. Coming
up with an effective passphrase can be a chore, but the added
security is worth it.
If you forget a passphrase, you are out of luck: the corresponding
SSH private key becomes unusable because you can't decrypt it.
The same encryption that makes SSH so secure also makes passphrases
impossible to recover. You have to abandon your SSH key, generate a
new one, and choose a new passphrase f
or it. You must also install the new
public key on every machine that had your original.
| | |
6. Key Management and Agents | | 6.3. SSH Agents |