III. MATERIALES Y MÉTODOS
3.5. METODOLOGÍA EXPERIMENTAL
At an administrative level, keys are managed by keytool, a utility supplied with the JRE. This tool allows you to create new keys, import digital certificates, export existing keys, and generally interact with the key management system.
The keytool has only a command−line interface; in this section, we'll look at the typical commands that add, modify, list, and delete entries in the keystore. Along the way, we'll see how you can create your own keys and certificates and how to get a valid certificate from an official certificate authority. As we understand the operations provided by keytool, we'll be poised to understand the underlying Java API that we'll examine later in this chapter.
10.2.1 Global Options to keytool
Keytool implements 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 keytool prompt 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, like this:
−dname \
"CN=Scott Oaks, OU=JSD, O=Sun Microsystems, L=NY, 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. If this password is not provided on the command line, you will be prompted for it. This is 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.
For certain commands, the password may be omitted.
−keystore filename
Specify the name of the file that holds the keystore. The default value is $HOME/.keystore, as described before.
−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 the password is not provided on the command line, you will be prompted for it, which is the more secure way to enter this password.
−storetype storetype
Specify the type of keystore that the keytool should operate on. This defaults to the keystore 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.
Now we'll look at the various commands that are available within keytool, and along the way we'll build up a keystore that we'll use in examples in later chapters.
10.2.2 Creating a Key Entry
We'll start by creating a key entry that holds a private key and certificate. This is done by the following command, which creates the private key and a self−signed certificate that contains the corresponding public key:
−genkey
Generate a key pair and add that entry to the keystore. This command supports these global options:
−alias alias
−dname DN
−keypass keypass
−keystore keystore
−storepass storepass
−storetype storetype It also supports these options:
−keyalg AlgorithmName
Use the given algorithm to generate the key pair. The default for this option is DSA; you must use an algorithm name that is supported by a security provider that you have installed.
−keysize keysize
Use the given keysize to initialize the key pair generator. The default value for this option is 1024;
you must use a key size that is supported by the key algorithm you want to use.
−sigalg signatureAlgorithm
Specify the signature algorithm that will be used to create the self−signed certificate; this defaults to SHA1withDSA, which is supported by the Sun security provider. If you've specified a different key algorithm (e.g., RSA), you'll have a different default signature algorithm (e.g., SHA1withRSA).
−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 identifies 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 was not issued by a known CA.
However, the self−signed certificate can be used to obtain a certificate from a known CA, as we'll see in just a bit.
Here's how you use this command to create a key entry:
piccolo% keytool −genkey −alias sdo −keyalg RSA Enter keystore password: ******
What is your first and last name?
[Unknown]: Scott Oaks
What is the name of your organizational unit?
[Unknown]: JSD
What is the name of your organization?
[Unknown]: Sun Microsystems
What is the name of your City or Locality?
[Unknown]: NY
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=JSD, O=Sun Microsystems, L=NY, 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. We also chose to generate an RSA key pair since in later chapters, we'll want to use this key with SSL algorithms.
Be careful in selecting the values for the DN. Certain characters, such as commas, will become quoted.
Unfortunately, quoted strings cannot be verified by other CAs. Hence, if you see quotes in the generated DN, reenter the information so that it is not quoted.
While it is possible for a keystore to hold a key entry that stores a secret key, keytool itself does not support creating such entries. Those entries can only be created programatically.
10.2.3 Generating a Certificate Request
If we want someone to accept the key we just generated, we need to obtain a certificate from a known CA.
"Known" in this context means that we must already have the root certificate of the CA (e.g., in the cacerts file).
Which CA you choose is a complicated decision. As we've mentioned, CAs will take different steps to verify the identity of the person or organization to whom they issue a certificate. The certificate they issue will be verified by a different root certificate as a result: if you want a simple, free certificate with little verification of your identity, you can get a Thawte Personal Certificate. If you want something with more assurance as to your identity, you can pay for an SSL or developer's certificate from Thawte. That process takes longer since Thawte will do an extensive check to make sure that you are who you represent yourself to be.
So the issue here is to whom you will present your certificate and what level of verification they will accept.
For our testing purposes, the Thawte Personal Certificate will do just fine; if you're presenting a certificate to a developer's association, they may require a Verisign Class 3 certificate, and so on. Of course, the converse of this relationship should also hold: when someone presents you with a certificate, you should check who issued it and what type it is in order to determine how careful the CA was in supplying the certificate.
In order 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 global options:
−alias alias
−keypass keypass
−keystore keystore
−storepass storepass
−storetype storetype
−v
It also supports these options:
−sigalg signatureAlgorithm
Use the given algorithm to sign the CSR. The CSR must be signed by an algorithm the CA expects,
and the algorithm must be consistent with the key being verified. The default algorithm will be based on the type of key held by the alias.
−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.
Here's how to generate the CSR:
piccolo% keytool −certreq −alias sdo −file sdoCSR.cer Enter keystore password: ******
Enter key password for <sdo>: ******
If you used the same password for the keystore and the key itself, you are only prompted once for the password.
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. For simple testing, the quickest way to proceed is to register for a personal certificate at http://www.thawte.com/. Once you've received email from Thawte and continued with the registration process, you will arrive at https://www.thawte.com/cgi/personal/cert/enroll.exe; make sure to follow the section entitled "Developers of New Security Applications ONLY." Don't be dissuaded by the statements that you should only follow that link if you know what you're doing; that's the section on their web site that allows you to paste in a CSR. However, if you do this you must generate the initial keypair with a special value in the CN field; Thawte will tell you what that value is when you follow the links to request the certificate.
No matter which CA you use, you'll eventually be sent back the certificate, which will be in RFC 1421 format.
10.2.4 Importing a Certificate
When the response from the CA comes, we must save it to a file from which we can import it. In order to import the certificate, we must already have the root certificate in our list of trusted certificate authorities, or we must be prepared to accept the root certificate that keytool presents to us. To import the certificate, 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 global options:
−alias alias
−keypass keypass
−keystore keystore
−storepass storepass
−storetype storetype
−v
It also supports these options:
−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.
The certificate file sent by a CA will contain a certificate chain. The first certificate in the chain will be for the alias itself and will be issued by the certificate authority; the next certificate in the chain will be for the certificate authority and will be self−signed (a root certificate) or issued by another certificate authority, and so on until a self−signed certificate is present. While the encoding of the chain is defined by RFC 1421, the format of the chain itself is often referred to as a Netscape certificate chain or a PKCS #7 certificate chain. Keytool can read either format; if your CA gives you a choice of formats, pick either one.
−noprompt
Do not prompt the user about whether or not the certificate should be accepted. When this option is present, the certificate is always installed. Otherwise, if the root certificate in the chain is not from a trusted certificate authority, the user will be prompted whether or not to install the certificate chain.
When you import a certificate from an unrecognized CA, the information contained in that certificate is printed out; this information includes the fingerprint of the certificate and the distinguished names of the issuer and the principal. 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.
−trustcacerts
Use the cacerts file to obtain trusted certificates from certificate authorities that have signed the certificate that is being imported. Without this option, no CAs are considered trusted, and the user will always be asked whether or not to accept the certificate (unless, of course, the noprompt option is in effect).
If we saved the response from the CA in the file sdo.cer, here's how we'd import it into our keystore:
piccolo% keytool −import −file sdo.cer −alias sdo −trustcacerts Enter keystore password: ******
Certificate reply was installed in keystore
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 signature is invalid (which would be the case if data in the certificate had been modified in transit).
As a result of this command, the state of the sdo entry has significantly changed:
When we created the key entry, the sdo entry had a single certificate; that certificate was issued by sdo.
•
After the import command, the sdo entry has two or more certificates in its certificate chain: the first certificate is issued by the certificate authority and has a principal of sdo; the last certificate is the CA's self−signed certificate. There may be intermediate certificates in this chain.
•
10.2.5 Creating a Certificate Entry
Certificate entries in a keystore are always created by importing an existing certificate. The certificate may be the root certificate of a known CA (or the internal CA for your enterprise), or it may be a certificate that
verifies the identity of someone with whom you will exchange information. For example, if I'm going to send you a digitally signed message, you must have my certificate (issued by a CA) within your keystore.
Certificate entries are created with the same import command that we just looked at. Let's say that I send you my certificate, and you've saved it to the file fromsdo.cer. You'd import it into your keystore like this:
piccolo% keytool −import −alias sdo −file fromsdo.cer
Enter keystore password: ******
Owner: [email protected], CN=Thawte Freemail Member Issuer: CN=Personal Freemail RSA 2000.8.30, OU=Certificate Services, O=Thawte, L=Cape Town, ST=Western Cape, C=ZA
Serial number: 3df48
Valid from: Thu Dec 28 22:18:29 EST 2000 until: Fri Dec 28 22:18:29 EST 2001 Certificate fingerprints:
MD5: BE:E1:5C:54:E8:60:D4:09:7D:D8:C5:16:56:CA:72:5A SHA1: 4F:22:2D:E9:1C:7D:A6:D6:E4:1B:92:A5:CC:BE:DC:E8:DD:65:F6:45
Trust this certificate? [no]: yes Certificate was added to keystore
Note that in this example, we haven't used the cacerts file to verify the certificate automatically (and since the given CA doesn't exist in the cacerts file, that would fail anyway). This causes keytool to print out the certificate information; you should examine and verify its fingerprint before deciding whether or not to trust the certificate.
10.2.6 Modifying Keystore Entries
There is no 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 before generating a CSR request.
This command supports the following global options:
−alias alias
−dname DN
−keypass keypass
−keystore keystore
−storepass storepass
−storetype storetype It also supports these options:
−sigalg algorithmName
Use the given algorithm to generate the signature in the self−signed certificate.
−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 global options:
−alias alias
−keypass keypass
−keystore keystore
−storepass storepass
−storetype storetype
−v
It also supports these options:
−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. Again, it is more secure to respond to a prompt (because the password is masked) than it is to supply it in plain text at the command line.
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 global options:
−alias alias
−keystore keystore
−storepass storePassword
−storetype storetype
−keypass originalPassword
It also supports this option:
−new newPassword
Specify the new password for the entry. If this option is not supplied, you will be prompted for the new password.
Changing the password is one way to migrate entries from a JKS to a JCEKS keystore since you can specify a
new storetype when you do so:
piccolo% keytool −keypasswd −alias sdo −storetype jceks
If you began with a JKS keystore, you'll end up with a JCEKS keystore after this command. Note that you can use this trick with other commands (e.g., the storepasswd command); anything that writes out a new keystore will change its format. However, the advantage of the JCEKS keystore is that the password
associated with key entries is strongly encrypted, and the key entry password will not be reencrypted by other commands. Hence, to convert effectively between JKS and JCEKS, you must use the keypasswd command for each key alias in your keystore.
10.2.7 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
Delete the entry of the specified alias. If a certificate entry for a certificate authority is deleted, there is