Manages a database of entities (people, companies, etc.) and their public
and private keys and certificates. Also generates and verifies signatures
for archive files.
javakey is the SUN security provider command-line tool
whose primary use is to generate digital signatures for archive files.
A signature verifies that a file came from a specified entity (a
"signer"). In order to generate a signature for a particular file,
the signer must first have a public/private key pair associated with it,
and also one or more certificates authenticating its public key. Thus,
javakey is also used to build and manage a persistent database of
entities and their keys and certificates, as well as indications as to
whether or not each entity is considered "trusted."
Identities, Signers, and Keys
There are two types of entities managed by javakey:
identities and signers.
Identities are real-world entities such as people, companies or
organizations that have a public key associated with them.
An identity may also have associated with it one or more certificates
authenticating its public key. A certificate is a digitally signed statement
from one entity, saying that the public key of some other entity has a
particular value. (See Certificates.)
Signers are entities that have private keys in addition to
corresponding public keys. Private keys differ from public keys in that
they can be used for signing. Prior to signing any files, a signer must
have a public and private key pair associated with it, and at least one
certificate authenticating its public key.
In javakey, you can either import existing keys or generate new
ones for association with identities and signers. Similarly, you can either
import existing certificates or generate new ones.
Database usernames for identities and signers
All entities (identities and signers) have a username local to
the database managed by javakey. A username is specified when you
add the entity to the database using the -c (create identity) or
-cs (create signer) option. Subsequent javakey commands must
use this same username to refer to the entity. For example, suppose a
trusted signer is created and assigned duke as a username, via
the following command:
javakey -cs duke true
Then to generate a DSA public/private key pair using a key size of 512 bits
for this signer, you would use the following command:
javakey -gk duke DSA 512
Associating trust with identities and signers
In JDK 1.1, the client (e.g., end user or system administrator) can
use javakey to declare certain entities to be trusted.
The appletviewer allows any downloaded applets in JAR files signed (using
javakey) by a trusted entity to run with the same full rights
as local applications. That is, such applets are not subject to the
"sandbox" restrictions of the original Java security model. (Fine point:
The database managed by javakey must also hold a copy of a certificate
for the public key of the entity that signed the JAR file, so that the
signature can be authenticated.) Later releases will provide greater
granularity in the allowable trust levels.
The database managed by javakey stores the entity usernames, their
certificates, and each entity's trust
level. When you add an entity to the database, you can declare
it at that time to be either trusted or untrusted (the default).
javakey -cs duke true
javakey -cs bob false
javakey -cs morty
The first example creates the signer named duke as a
trusted entity. The next two create the signers bob
and morty as untrusted. If you don't specify a trust level,
then by default, the entity is untrusted.
You can later on declare a previously untrusted entity
to be trusted:
javakey -t morty true
You can also declare a previously trusted entity to be untrusted:
javakey -t duke false
Use
javakey -ld
to see the state of the entire entity database.
Use
javakey -li morty
to see the state of one entity (in this case, morty) in
the database.
Database Location
The database managed by javakey is by default stored in a file named
identitydb.obj.
Since the database may contain private keys, it should be kept in a
secure location. The default is for the database to be stored in the
JDK installation directory. If a different
location is desired, it can be specified by setting the value of the
identity.database property in the master security properties
file, called java.security. That file resides in the JDK security
properties directory, in java.home\lib\security, where
java.home is the directory where the JDK is installed.
For example, you could specify the location via the following:
Note: The directory separators in the above example cannot be the single backslashes normally used as directory separators when specifying file pathnames in Win95 or Windows NT. Rather, javakey requires them to be either the double backslashes shown or single slashes, as in
javakey lets you import, create, display, and save certificates.
A certificate is a digitally signed statement from one entity (a signer),
saying that the public key of some other entity has a particular value.
If you trust the entity that signed a certificate, you trust that the
association in the certificate between the specified public key and another
particular entity is authentic.
javakey currently handles X.509 certificates. The remainder
of the examples in this section pertain to X.509 certificates.
In order to generate a certificate, you must first create a directive file
in which you supply
information about the issuer (the signer signing the certificate),
information about the subject (the entity whose public key is being
authenticated by the certificate),
information about the certificate itself, and, optionally,
the name of the signature algorithm to be used (if you don't want DSA).
the name of a file to which to store a copy of the certificate.
Generate a certificate by using the -gc
option and specifying a directive file, as in
javakey -gc dukeCertDirFile
javakey will create a certificate, using the information supplied
in the directive file. It also uses information stored in the database, such
as the public key of the entity whose key is to be certified, and the private
key of the issuer (required in order to sign the certificate).
Here is an example of a certificate directive file, followed by an
explanation of the arguments:
#
# Information about the issuer (required).
#
issuer.name=jsmith
#
# The certificate to use for the signing (required if this is not self-signed).
#
issuer.cert=1
#
# Information about the subject (required).
#
subject.name=mlaunay
subject.real.name=Marie Launay
subject.org.unit=JavaSoft
subject.org=Sun MicroSystems
subject.country=Switzerland
#
# Information about the certificate (required).
#
start.date=1 Jan 1997
end.date=15 Jan 1997
serial.number=1001
#
# Signature algorithm to be used (only required if you don't want DSA used).
#
signature.algorithm=MD5/RSA
#
# Name of the file to which to save a copy of the certificate (optional).
#
out.file=cert.cer
All certificate directive file arguments are required, unless specified
otherwise:
issuer.name and subject.name
Database usernames. issuer.name is the name of the signer
signing and issuing the certificate. subject.name is the name
of the entity (identity or signer) whose public key is being authenticated
by the issuer of the certificate.
issuer.cert
Specifies which of the issuer's certificates is to be used to
sign the certificate file, thereby authenticating the subject's public key.
Its value should be the number that javakey previously assigned to
the issuer's certificate when it generated it (or imported it). You can see
which numbers javakey assigns to certificates by viewing the output of the
-ld or
-lijavakey option. Note:
This issuer.cert property is only required if the certificate being
generated is not self-signed. (A self-signed certificate is one for
which issuer.name equals subject.name.)
subject.real.name, subject.org.unit, subject.org, and
subject.country
X.500 distinguished name components. These components refer to the
subject's common name, organizational unit, organization, and country, respectively.
start.date and end.date
Strings specifying the certificate's validity start and expiration
dates (and optionally times). The certificate is valid from the start date
and time to the end date and time. The start and end date strings can be
any strings accepted by the java.util Date method that takes
a String argument. A date without a time specified is interpreted as
meaning the start of the specified date.
serial.number
The serial number. For a given issuer, this number must be unique, to
distinguish this certificate from other certificates signed by the issuer.
signature.algorithm
The name of the signature algorithm to be used to sign the certificate.
This argument is optional. If there is no signature.algorithm
specified, DSA (Digital Signature Algorithm) will be used; in that case, the
signer's private and public keys must be for the DSA algorithm. A non-DSA
algorithm can only be used if (1) the specified name is a standard
algorithm name, (2) there is a statically installed provider
supplying an implementation for the algorithm, and (3) the signer's keys
are suitable for the specified algorithm. For example, if the value of
the signature.algorithm property is MD5/RSA or
SHA-1/RSA, then the signer's keys must be RSA keys.
out.file
The name of a file to which to save the certificate. This argument is
optional.
Using javakey, it is possible to display, import, and export
certificates stored as files.
To display a certificate stored in a file, use the -dc option, as in
javakey -dc certfile.cer
This displays information about the certificate stored in the file
certfile.cer, showing
the certificate type (currently, X.509v1).
information about the subject.
information about the public key:
the algorithm and its parameters (currently, DSA and its p, q, and
g parameter values).
the unparsed key bits.
the certificate validity dates.
information about the issuer.
information about the signature algorithm used.
the certificate serial number, in hexadecimal.
To import a certificate from a file, use the -ic option, as in
javakey -ic joe jcertfile.cer
This sample command imports the certificate in the file jcertfile.cer
and associates it with joe.
To export a certificate to a file, use the -ec option, as in
javakey -ec jane 2 janecertfile.cer
This sample command exports jane's certificate #2 to the file
janecertfile.cer. The certificate number must be the number that
javakey previously assigned to her certificate when it generated
it (or imported it). You can see which numbers javakey assigns to
certificates by viewing the output of the
-ld or the
-lijavakey option.
Java ARchive files (JAR files) are a new feature of JDK1.1. This feature
enables the packaging of class files, images, sounds, and other digital data
in a single file for faster and easier distribution. JDK1.1 includes a tool
named jar that enables developers to
produce JAR files.
javakey can be used to sign and verify JAR files. (Note;
verification is not yet implemented.) Java licensees are expected to honor
the signature generated using javakey.
At this time, javakey can sign the JAR file using DSA
(Digital Signature Algorithm) or, in some cases, the MD5/RSA algorithm.
That is, if the signer's public and private keys are DSA keys,
javakey will sign the JAR file using DSA. If the signer's keys are
RSA keys, javakey will try to sign the JAR file
using the MD5/RSA algorithm. This is only possible if
there is a statically installed provider
supplying an implementation for the MD5/RSA algorithm.
For both the DSA and MD5/RSA algorithms, anyone who wants to sign files has
both a public key and a private key. The private key is
used for signing, and a certificate of the public key is included in
the signature file (in a PKCS #7 block).
Signing JAR Files
Signing a JAR file involves generating a signature for a given signer and
including that signature in a given JAR file. It requires the signer to be in
the database managed by javakey, along with an associated key pair and
at least one X.509 certificate. Like certificate generation, generating a signature is
directive-based. Each directive file contains a signer
profile. A sample directive file might look like this:
#
# JAR signing directive. This is the directive file used by javakey to
# sign a JAR file.
#
# Which signer to use. This signer must be in the database.
signer=duke
# Certificate number to use for this signer. This determines which
# certificate will be included in the PKCS#7 block. This is mandatory
# and is 1-based. Its value should be the number that javakey
# previously assigned to the signer's certificate when it generated it
# (or imported it). You can see which numbers javakey assigns
# to certificates by viewing the output of the
# -ld or -li javakey option.
cert=1
# Certificate chain depth of a chain of certificates to include. This is
# currently not supported.
chain=0
# The name to give to the generated signature file and associated signature
# block. This must be 8 characters or less.
# The generated signature file and associated signature block will have
# this name, with the .SF and .DSA extensions, respectively.
# In this example, the files will be DUKESIGN.SF and DUKESIGN.DSA.
signature.file=DUKESIGN
# (Optional) The name to give to the signed JAR file.
out.file=signedJar.jar
Once the JAR file and the directive file have been created, the javakey command to sign a JAR file can be used. It is:
javakey -gs directivefile jarfile
where directivefile is the name (and path) of the directive file,
and jarfile is the name (and path) of the JAR file.
The output of this command is a signed JAR file whose name will be
the name specified by the value of the out.file property, if any,
specified in the directive file. If there is no out.file property, the signed JAR
file name will be the same as that of the initial JAR file, but with the suffix .sig.
The generated .SF and .DSA files will be added to the JAR file, in a
META-INF directory. If the base name for these files is
DUKESIGN, as in the example above, the files added will be:
META-INF\DUKESIGN.SF
META-INF\DUKESIGN.DSA
Any files with these names in the signed JAR file will be overwritten.
Note: options may be specified with or without a preceding minus sign (-).
Only one option may be specified per javakey command.
-c identity{true|false}
Creates a new identity with database username identity. The optional
true or false designation specifies whether or not
the identity is to be considered trusted. (The default is false.)
For example, the following creates an identity named jane, and
specifies that she is trusted:
javakey -c jane true
-cs signer{true|false}
Creates a new signer with database username signer. The optional
true or false designation specifies whether or not
the signer is to be considered trusted. (The default is false.)
-t idOrSigner{true|false}
Sets (or resets) the trust level for the specified identity or signer.
-l
Lists the usernames of all entities (identities and signers) in the database
managed by javakey.
Provides detailed information about the specified identity or signer.
-r idOrSigner
Removes the specified identity or signer from the database.
-ik identity keysrcfile
Imports the public key in the file keysrcfile, associating it with
the specified identity. The key must be in X.509 format.
-ikp signer pubfile privfile
Imports the key pair (the public key in the file pubfile and the
private key in the file privfile), associating them with the
specified signer. The keys must be in X.509 format.
-ic idOrSigner certsrcfile
Imports the public key certificate in the file certsrcfile,
associating it with the specified entity (identity or signer). If a public
key has already been associated with the entity in the datase,
javakey ensures that it is the same as the public key certified in
certsrcfile, and will report an error if they're not the same. If
the entity does not yet have a public key associated with it, javakey
will create the association, using the public key in certsrcfile.
-ii idOrSigner
Sets information for the specified identity or signer. After you type in an
"import information" command such as
javakey -ii jane
you will be instructed to type as many lines of information you want to
supply for jane, ending with a line containing a single period to
signal the end of the information.
-gk signer algorithm keysize {pubfile}
{privfile}
Generates a key pair (a public key and associated private key) for the
specified signer using the specified algorithm, generating
keys of length keysize bits. If a file pubfile is specified,
the public key will be written to that file. If, in addition, a file
privfile is specified, the private key will be written to that file.
Do the latter with great care; private keys must remain private or your
security system is compromised.
The keysize limits for the algorithm, if any, are those described in
Appendix B of the
Java Cryptography Architecture API Specification & Reference.
Note: javakey can always generate DSA (Digital Signature Algorithm)
keys. It can generate keys for a different algorithm only if (1) the
specified name is a
standard key generation algorithm name such as RSA, and
(2) there is a statically installed provider
supplying an implementation for the specified key generation algorithm.
Please note that there is no way to supply algorithm-specific key
generation parameters, such as the p,
q, or g parameters for the DSA algorithm.
-g signer algorithm keysize {pubfile} {privfile}
Shortcut for the -gk command to generate a key pair for the specified signer.
Exports the certificate numbered certnum from the specified
idOrSigner to the file certoutfile. The certificate number
must be the number that javakey previously assigned to the
certificate when it generated it (or imported it). To see which numbers
javakey assigns to certificates, view the output of the -ld (for
all entities) or -li (for a particular entity) option.
-ek idOrSigner pubfile {privfile}
Exports the public key for the specified identity or signer, and
optionally the private key (for a signer), to the specified
file(s). The keys are encoded in X.509/DER format.
-gs directivefile jarfile
Signs the specified JAR (Java ARchive) file according to information supplied
in the directivefile. See
JAR Files and Digital Signatures.
EXAMPLES
To create a trusted identity called jane and a trusted signer called
joe, use the following commands:
javakey -c jane true
javakey -cs joe true
Suppose jane sends her public key by email to joe and
he stores the key in the file named \tmp\jane_pubkey. It must
be encoded in X.509/DER format. To import and associate that key with
jane's identity in the persistent database managed by javakey,
joe (or a system administrator) enters the following command:
javakey -ik jane \tmp\jane_pubkey
Let's also assume joe has a public and private key pair that he used
in another context. He now wants to associate that key pair with his own
username identifier in the database. He does this with the following command,
assuming that the public key is stored in \tmp\joe_pubkey and the
private key in \tmp\joe_privkey:
javakey -ikp joe \tmp\joe_pubkey \tmp\joe_privkey
The keys must both be in X.509 format. They must be for the same
algorithm, of course.
To generate a new key pair for joe instead of using an existing
key pair, the following command could be used:
javakey -gk joe DSA 512 \tmp\joe_pubkey
This command creates a DSA key pair, with 512-bit keys, and associates it
with joe. The -gk command also optionally saves a
copy of the public key in a file. The example uses the file
\tmp\joe_pubkey. One reason joe might want to save
the public key in a file is so that he can mail a copy of it to jane
or anyone else who needs it (e.g., to verify joe's digital signatures
of files). This command also optionally lets joe specify a file to
which to save the private key, if needed. However, saving the private key to
a file should be done with great care.
Before joe can sign any files, he must have one or more certificates
associated with him, authenticating his public key. In order to generate a
certificate for him, a directive file must first be created, specifying
various information about joe and about the certificate issuer, the
certificate's validity dates, etc. Suppose such a file has been generated (see
Certificates), and its name is
joeCertDirectiveFile, in the \tmp\ directory. A
certificate for joe can then be generated by the command
javakey -gc \tmp\joeCertDirectiveFile
As described in JAR Files and Digital Signatures,
signing a JAR file also requires the use of a directive file providing
information required for the signature, such as the signer name and the
number of the certificate to use for that signer. The command to sign the
JAR file named jarfileA.jar, using the directive file
joeJarDirectiveFile is:
http://java.sun.com/security/signExample/: A
simple step-by-step demo of how you can experiment with
code signing, using the JDK 1.1 tools (javakey, jar, and
appletviewer).