Appendix A. Security Tools
In this appendix, we'll discuss the tools that come with the
JDK that allow developers, end users, and system administrators to
deal with the security aspects of the Java platform. These tools are
only available in Java 1.2,[1] since they primarily deal with operations that require
the support of 1.2.[2] As Java's security model advances, these
tools have become primary interfaces to establishing a secure sandbox
for Java applications.
To a lesser extent, these tools have become an interface for
establishing a secure sandbox for Java applets as well. However, as
we've seen, not all the security features of the Java platform
have yet been uniformly adopted by all browsers. In part, it is a
problem with logistics. As this book went to press, Java 1.2 was
still a new release. Clearly it will take some time before these new
features can be propagated to browsers. Part of the problem, though,
lies in the fact that Java applications (and Java browsers)
ultimately decide upon their own security features.
This last fact is true of your own applications as well: you can
certainly use the keytool utility that comes
with the JDK to manage your public key/private key databases. But if
it is appropriate, you may want to replace (or at least supplement)
the keytool with your own key management tool
that handles some of the situations we discussed in Chapter 11, "Key Management".
A.1. The keytool
In Chapter 11, "Key Management" we discussed the KeyStore
class, which provides an interface to a key management system. The
Java platform comes with a
tool--keytool--that provides an
administrative interface to that class. Keytool
allows end users and system administrators to add, delete,
and modify entries in the keystore (provided that they have
sufficient permissions, of course).
When we discussed the KeyStore class, we
mentioned that it had some limitations that may lead you to write
your own implementation of that class. The good news is that if you
write such a class, you may still use keytool to
administer your set of keys. Since keytool uses
the standard interface provided by the KeyStore
class, it will be (mostly) compatible with any new class that you
install into that interface (we'll remind you how to do that at
the end of this appendix). However, there are some exceptions to
this: keytool itself places some restrictions
upon the algorithms that may be used to support particular keys.
Before we examine the workings of keytool,
let's review a few objects that we talked about in Chapter 11, "Key Management". When we discussed the
KeyStore class, we defined the following terms:
-
keystore
-
The keystore is
the file that actually holds the set of keys;
keytool operates on this file. In other
implementations of the KeyStore class, the
keystore may not be a file--the keys in that implementation may
be held in a database or some other structure. Regardless, we refer
to the set of keys on disk (or wherever they are located) as the
keystore.
In keytool, this file is called
.keystore and is held in the directory specified
by the property user.home. On Unix systems, this
directory defaults to the user's home directory (e.g.,
$HOME); on Windows systems, this directory
defaults to the concatenation of the HOMEDRIVE and HOMEPATH
environment variables (e.g., C:\).
-
alias
-
An alias is a shortened, keystore-specific
name for an entity that has a key in the keystore. I choose to store
my public and private key in my local keystore under the alias
"sdo"; if you have a copy of my public key, you may use
that alias, or you may use another alias (like
"ScottOaks"). The alias used for a particular entity is
completely up to the discretion of the individual who first enters
that entity into the keystore.
-
DN (distinguished name)
-
The
distinguished name for an entity in the keystore is a subset of its
full X.500 name. This is a long string; for example, my DN is:
Class Definition
CN=Scott Oaks, OU=SMCC, O=Sun Microsystems, L=New York, S=NY, C=US
DNs are used by certificate authorities to refer to the entities to
whom they supply a certificate. Hence, unlike an alias, the DN for a
particular key is the same no matter what keystore it is located in:
if I send you my public key, it will have the DN encoded in the
public key's certificate.
However, nothing prevents me from having two public keys with
different DNs (I might have one for personal use that omits
references to my place of employment). And there is no guarantee that
two unrelated individuals will not share the same DN (in fact, you
can count on this type of namespace collision to occur).
-
key entries and certificate entries
-
There are two types of entries in the keystore:
key entries and certificate entries. A
key entry is an entry that has a private key as well as a
corresponding public key. The public key in this case is embedded in
a certificate, and there is a chain of certificates that vouch for
the public key.
A certificate entry, on the other hand, does not contain a private
key; it contains only a public key held in a certificate. In
addition, there is only a single certificate associated with this
entry.
With that in mind, we'll look at the various commands that
keytool provides. At present,
keytool only has a command-line interface;
we'll look at the typical commands that add, modify, list, and
delete entries in the keystore.
A.1.1. Global Options to keytool
Keytoolimplements a number of global
options--options that are available to most of its commands.
We'll list these as appropriate for each command, but
here's an explanation of what they do:
-
-alias alias
-
Specify the alias the operation
should apply to (e.g., -alias sdo). The default
for this value is "mykey."
-
-dname distinguishedName
-
Specify the distinguished name. There
is no default for this value, and if you do not specify it on the
command line, you will be prompted to enter it when it is needed.
Letting keytoolprompt you is generally easier,
since the tool will prompt for the name one field at a time.
Otherwise, you must enter the entire name in one quoted string, e.g.:
Class Definition
-dname \
"CN=Scott Oaks, OU=SMCC, O=Sun Microsystems, L=New York, S=NY, C=US"
-
-keypass password
-
Specify the password used to protect the
entire keystore. Access to any element in the keystore requires this
global password (programmatically, this is the password that is
passed to the load() method of the
KeyStore class). If this password is not
provided on the command line, you will be prompted for it. This is
generally more secure than typing it on a command line or in a script
where others might see it. Passwords must be at least six characters
long.
Note that even though the KeyStore class allows
you to read entries from the keystore without this password,
keytool does not.
-
-keystore filename
-
Specify the name of the file that
holds the keystore (programmatically, this file will be opened and
passed as the input stream argument to the
load() method of the
KeyStore class). The default value of this is
the .keystore file described above.
-
-storepass password
-
Specify the password used to protect a particular entry's
private key. This is usually not (and should not be) the same as the
global password. There should be a different password for each
private key that is specific to that entry. This allows the keystore
to be shared among many users. If this password is not provided on
the command line, you will be prompted for it, which is generally the
more secure way to enter this password.
-
-storetype storetype
-
Specify the type of keystroke that the keytool should operate on. This defaults to the keystroke type in the java.security file, which defaults to JKS, the keystore type provided by the Sun security provider.
-
-v
-
Verbose--print some information about the operations
keytool is performing.
A.1.2. Adding a Certificate Entry
In order to add a certificate
entry to the database, you use this command:
-
-import
-
Import a certificate into the
database. This command either creates a new certificate entry or
imports a certificate for an existing key entry. This command
supports the following options:
-
-alias alias
-
-keypass keypass
-
-keystore keystore
-
-storepass storepass
-
-storetype storetype
-
-v
-
-file inputFile
-
The file containing the certificate
that is being imported. The certificate must be in RFC 1421 format.
The default is to read the data from System.in.
-
-noprompt
-
Do not prompt the user about whether
or not the certificate should be accepted.
-
-trustcacerts
-
Use the cacerts file to obtain trusted certificates from certificate autorities that have signed the certificate that is being imported.
When you import a certificate, the information contained in that
certificate is printed out; this information includes the
distinguished names of the issuer and the principal, and the
fingerprint of the certificate. Well-known certificate authorities
will publish their fingerprints (on the Web, in trade papers, and
elsewhere). It is very important for you to verify the displayed
fingerprint with the published fingerprint in order to verify that
the certificate does indeed belong to the principal named in the
certificate.
Let's say that I have a certificate for the ACME certificate
authority in the file amce.cer. I can import it
with this command:
Class Definition
piccolo% keytool -import -alias acme -file acme.cer
Enter keystore password: ******
Owner: CN=ACME, OU=ACME CA Services, O=ACME Inc., L=New York, S=NY, C=US
Issuer: CN=ACME, OU=ACME CA Services, O=ACME Inc., L=New York, S=NY, C=US
Serial Number: 34cbd057
Valid from: Sun Jan 25 18:52:55 EST 1998 until: Sat Apr 25 19:52:55 EDT 1998
Certificate Fingerprints:
MD5: 51:4E:52:2C:1B:14:38:52:DB:30:5D:46:A9:46:FF:BB
SHA1: 9F:B2:18:4A:63:8B:F8:EB:A6:A0:56:DB:C7:1B:B3:CC:F5:4B:BA:72
Trust this certificate? [no]: yes
After typing in the command, keytool prints the
given names, serial number, and fingerprints, and asks for
verification before it actually enters the certificate into the
keystore. After receiving a yes answer, the entry is made.
A.1.3. Adding a Key Entry
To add a key entry to the database
(that is, an entry containing a private key), use this command:
-
-genkey
-
Generate a key pair and add that entry
to the keystore. This command supports these options:
-
-alias alias
-
-dname DN
-
-keypass keypass
-
-keystore keystore
-
-storepass storepass
-
-storetype storetype
-
-keyalg AlgorithmName
-
Use the given algorithm to generate
the key pair. For the default Sun security provider, the name must be
DSA, which is also the default value for this option. Despite the
presence of this option, you cannot really specify another algorithm
name, nor, for that matter, can you use a non-Sun DSA provider.
Internally, keytool expects the key generator to
produce keys that belong to a specific class in the
sun package.
-
-keysize keysize
-
Use the given keysize to initialize
the key pair generator. The default value for this option is 1024.
Since the key is a DSA key, the value must be between 512 and 1024
and be a multiple of 64.
-
-sigalg signatureAlgorithm
-
Specify the signature algorithm that
will be used to create the self-signed certificate; this defaults to
SHA-1/DSA, which is supported by the Sun security provider. Like the
key algorithm, this option is not particularly useful at present,
since you cannot use your own security provider classes to implement
the signature.
-
-validity nDays
-
Specify the number of days for which
the self-signed certificate should be valid. The default value for
this option is 90 days.
The key entry that is created in this manner has the generated
private key. In addition, the public key is placed into a self-signed
certificate; that is, a certificate that identitifies the holder of
the public key (using the distinguished name argument) and is signed
by the holder of the key itself. This is a valid certificate in all
senses, although other sites will probably not accept the certificate
since it is not signed by a known certificate authority (CA). But
the self-signed certificate can be used to obtain a certificate from
a CA.
In order to use this self-signed certificate to obtain a certificate
from a CA, you must first generate a certificate
signing request (CSR). The CSR contains the distinguished name and
public key for a particular alias and is signed using the private key
of the alias; the CA can then verify that signature and issue a
certificate verifying the public key. CSRs are generated with this
option:
-
-certreq
-
Generate a certificate signing
request. This command supports the following options:
-
-alias alias
-
-keypass keypass
-
-keystore keystore
-
-storepass storepass
-
-storetype storetype
-
-v
-
-sigalg signatureAlgorithm
-
Use the given algorithm to sign the
CSR. This option is not presently useful, as the internal design of
keytool only supports SHA-1/DSA signatures
created by the Sun security provider.
-
-file outputFile
-
Store the CSR in the given file. The
format of the CSR is defined in PKCS#10. The default is to write the
CSR to System.out.
Once you have the CSR in a file, you must send it to the CA of your
choice. Different CAs have different procedures for doing this, but
all of them will send you back a certificate they have signed that
verifies the public key you have sent to them. There are a few
different formats in which the CA will send back a certificate; the
only format that is presently supported by
keytool is RFC 1421 (so you should use a CA that supports
this format, of course). You must also use a CA for whom you have a
certificate entry (but the CA will often send you its self-signed
certificate anyway).
Once you've received the file containing the new certificate,
you can import it into the keystore using the
-import command we discussed previously.
Here's an example of how all these commands can be used to
create an entry with a private key and a certified public key. First,
we must create the entry:
Class Definition
piccolo% keytool -genkey -alias sdo
Enter keystore password: ******
What is your first and last name?
[Unknown]: Scott Oaks
What is the name of your organizational unit?
[Unknown]: SMCC
What is the name of your organization?
[Unknown]: Sun Microsystems
What is the name of your City or Locality?
[Unknown]: New York
What is the name of your State or Province?
[Unknown]: NY
What is the two-letter country code for this unit?
[Unknown]: US
Is <CN=Scott Oaks, OU=SMCC, O=Sun Microsystems, L=New York, S=NY, C=US> correct?
[no]: yes
Enter key password for <sdo>
(RETURN if same as keystore password): ******
At this point, we now have an entry for sdo in
the keystore. That entry has a self-signed certificate; note that we
had the tool prompt us for all the entries that comprise the DN
rather than attempting to type it all in on the command line. The
next step is to generate the CSR:
Class Definition
piccolo% keytool -certreq -alias sdo -file sdoCSR.cer
Enter keystore password: ******
The file sdoCSR.cer contains the CSR which must
now be sent to a CA. Note that we must send the CSR to an authority
for whom we already have a certificate entry--that is, for whom
we already have a public key. Otherwise, when the response to the CSR
comes, we will be unable to verify the signature of the CA that
issued the new certificate.
When the response does come, we must save it to a file. If we save it
to the file sdo.cer, we can import it with this
command:
Class Definition
piccolo% keytool -import -file sdo.cer -alias sdo
Enter keystore password: ******
Assuming that the certificate is valid, this imports the new
certificate into the keystore. The certificate is invalid if the
public key for sdo does not match the previously
defined public key in the database, or if the certificate was issued
by an authority for whom we do not possess a public key, or if the
certificate signature is invalid (which would be the case if data in
the certificate had been modified in transit).
The state of the sdo entry in the keystore has
changed during this example:
-
After the first command, the sdo entry has a
single certificate; that certificate is issued by
sdo.
-
After the import command, the sdo entry has two
certificates in its certificate chain: the first certificate is
issued by Acme and has a principal of sdo; the
second certificate is Acme's self-signed certificate (a copy of
the one that was imported when the Acme certificate entry was
created).
In programmatic terms, the getCertificateChain()
method of the KeyStore class will return an
array of one and two elements, respectively, for these cases.
We've mentioned in this section that in order to import a
certificate like this, the self-signed certificate of the certificate
authority must already be in the keystore. However, there's a
bootstrapping issue involved in this: how do you get the initial
certificates for the certificate authorities into a keystore?
The JDK comes with a set of five pre-installed certificates: four
from VeriSign, which issues certificates at different levels, and one
from RSA Data, Inc. These certificates are in the
cacerts file in the
${JAVAHOME}/lib/security directory. While those
certificates are not present in your .keystore
file, you can still import certificates into your
.keystore file by using the
-trustcacerts option: in that case, as long as
the certificate you're importing has been signed by one of the
authorities in the cacerts file, the import
operation will succeed.
Hence, if we'd sent our CSR request in the above example to
VeriSign and the returned certificate from VeriSign was stored in the
sdo.cer file, we could import it with this
comand:
Class Definition
piccolo% keytool -import -file sdo.cer -alias sdo -trustcacerts
If you want to use the certificates of the certificate authorities
programatically, you may do so by creating a keystore of type
JKS, and loading that keystore from the
cacerts file.
A.1.4. Modifying Keystore Entries
There is no practical way to modify a certificate entry in the
keystore. You may delete an existing entry and add a new one if
required.
There is one command that can modify the data within a key entry:
-
-selfcert
-
Change the certificate chain
associated with the target key entry. Any previous certificates
(including ones that may have been imported from a valid certificate
authority) are deleted and replaced with a new self-signed
certificate; this certificate can be used to generate a new CSR. The
public and private keys associated with the alias are unchanged, but
you may specify a new value for the DN on the command line. Hence,
one use for this command is to change the DN for a particular entry.
This command supports the following options:
-
-alias alias
-
-dname DN
-
-keypass keypass
-
-keystore keystore
-
-storepass storepass
-
-storetype storetype
-
-sigalg algorithmName
-
Use the given algorithm to generate the signature in the self-signed
certificate; as in other cases, this option only supports the DSA
algorithm no matter what algorithms may be supported by your security
provider.
-
-validity nDays
-
The number of days for which the self-signed certificate is valid.
The default is 90 days.
The -keyclone command is often used with this command, which can
create a copy of the original entry before the DN is changed:
-
-keyclone
-
Clone the target entry. The
cloned entry will have the same private key and certificate chain as
the original entry. This command supports the following options:
-
-alias alias
-
-keypass keypass
-
-keystore keystore
-
-storepass storepass
-
-storetype storetype
-
-v
-
-dest newAlias
-
The new alias name of the cloned entry. If this is not specified, you
will be prompted for it.
-
-new newPassword
-
The new password for the cloned entry. If this is not specified, you
will be prompted for it.
To change the password associated with a particular key entry, use
this command:
-
-keypasswd
-
Change the password for the given key entry. This command supports
the following options:
-
-alias alias
-
-keystore keystore
-
-storepass storePassword
-
-storetype storetype
-
-keypass originalPassword
-
-new newPassword
-
Specify the new password for the entry. If this option is not
supplied, you will be prompted for the new password.
A.1.5. Deleting Keystore Entries
There is a single command to delete either a key entry or a
certificate entry:
-
-delete
-
Delete the entry of the specified
alias. If a certificate entry for a certificate authority is deleted,
there is no effect upon key entries that have been validated by the
authority. This command supports the following options:
-alias alias
-keystore keystore
-storepass storepass
-storetype storetype
-v
A.1.6. Examining Keystore Data
If
you want to examine one or more entries in the keystore, you may use
the following commands:
-
-list
-
List (to
System.out) one or more entries in the keystore.
If an alias option is given to this command, only that alias will be
listed; otherwise, all entries in the keystore are listed. This
command supports the following options:
-
-alias alias
-
-keystore keystore
-
-storepass storepass
-
-storetype storetype
-
-v
-
-rfc
-
When displaying certificates, display them in RFC 1421 standard. This
option is incompatible with the -v option.
-
-export
-
Export the certificate for the given alias to a given file. The
certificate is exported in RFC 1421 format. If the target alias is a
certificate entry, that certificate is exported. Otherwise, the first
certificate in the target key entry's certificate chain will be
exported. This command supports the following options:
-
-alias alias
-
-keystore keystore
-
-storepass storepass
-
-storetype storetype
-
-v
-
-file outputFile
-
The file in which to store the certificate. The default is to write
the certificate to System.out.
-
-printcert
-
Print out a certificate. The input to this command must be a
certificate in RFC 1421 format; this command will display that
certificate in readable form so that you may verify its fingerprint.
Unlike all other commands, this command does not use the keystore
itself, and it requires no keystore passwords to operate. It supports
the following options:
-
-v
-
-file certificateFile
-
The file containing the RFC 1421 format certificate. The default is
to read the certificate from
System.in.
A.1.7. Importing a 1.1-Based Identity Database
The keystore in 1.2 is incompatible with the identity database in
1.1, but the keytool is capable of converting
between the two. To convert a 1.1 identity database to a 1.2
keystore, use this command:
-
-identitydb
-
Convert a 1.1 identity database. This command has the following
options
-
-v
-
-keystore keystore
-
-keypass keypass
-
-storepass storepass
-
-stereotype stereotype
-
-file db_file
-
The file name of the 1.1 identity database. The default for this is
identitydb.obj in the user's home
directory.
With this command, each trusted entry in the identity database will
be created as a key entry in the keystore. All other entries in the
identity database will be ignored.
A.1.8. Miscellaneous Commands
There are two remaining commands. The first allows you to change the
global password of the keystore:
-
-storepasswd
-
Change the
global password of the keystore. This command supports the following
options:
-
-keystore keystore
-
-storepass storepass
-
-storetype storetype
-
-v
-
-new newPassword
-
The new global password for the keystore. If you do not specify this
value, you will be prompted for it.
Finally, you can get a summary of all commands with this command:
-
-help
-
Print out a summary of the usage of
keytool.
| | |
13.9. Summary | | A.2. The jarsigner Tool |
Copyright © 2001 O'Reilly & Associates. All rights reserved.
|