BigInteger g, BigInteger p,
BigInteger q, BigInteger y
IvParameterSpec core
byte[] getIV IvParameterSpec
byte[] buf IvParameterSpec
byte[] buf, int offset PBEKeySpec JCE
String getPassword PBEKeySpecString pw
PBEParameterSpec JCE
int getIterationCount byte[] getSalt
PBEParameterSpec byte[] salt, int count
PKCS8EncodedKey−Spec core byte[] getEncoded
PKCSEncodedKeySpec byte[] key
RC2ParameterSpec JCE
byte[] getIV int getEffectiveKeyBits
RC2ParameterSpec int effective
RC2ParameterSpec int effective, byte[] iv
RC2ParameterSpec int effective, byte[] iv,
int offset RC5ParameterSpec
JCE byte[] getIV
int getRounds int getVersion
int getWordSize RC5ParameterSpec
int version, int rounds, int wordSize
RC5ParameterSpec int version, int rounds,
int wordSize, byte[] iv RC5ParameterSpec
int version, int rounds, int wordSize, byte[] iv,
int offset RSAKeyGenParameterSpec
core int getKeysize
BigInteger getPublicExponent
RSAKeyGenParameterSpec int size,
BigInteger exp RSAPrivateKeySpec
core BigInteger getModulus
BigInteger getPrivateExponent
RSAPrivateKeySpecBigInteger mod, BigInteger exp RSAPrivateKeySpecCrt
core BigInteger getModulus
BigInteger getPrivateExponent
BigInteger getPublicExponent
BigInteger getPrimeP BigInteger getPrimeQ
BigInteger getPrimeExponentP
BigInteger getPrimeExponentQ
BigInteger getCrtCoefficient
RSAPrivateKeySpecCrt BigInteger mod,
BigInteger publicExp, BigInteger privExp,
BigInteger primeP, BigInteger primeQ,
BigInteger primeExpP, BigInteger primeExpQ,
BigInteger crtCoeff RSAPublicKeySpec
core BigInteger getModulus
BigInteger getPublicExponent
RSAPublicKeySpec BigInteger mod,
BigInteger exp SecretKeySpec
JCE byte[] getEncoded
SecretKeySpecbyte[] key, String Algorithm
SecretKeySpecbyte[] key, int offset,
String Algorithm X509EncodedKey−Spec
core byte[] getEncoded
X509EncodedKeySpec byte[] key
9.4 Certificates
When you are given a public and private key, you often need to provide other people with your public key. If you sign a digital document using your private key, the recipient of that document will need your public key
in order to verify your digital signature.
The inherent problem with a key is that it does not provide any information about the identity to which it belongs; a key is really just a sequence of seemingly arbitrary numbers. If I want you to accept a document
that I digitally signed, I could mail you my public key, but you normally have no assurance that the key and the original email came from me at all. I could, of course, digitally sign the email so that you knew that it
came from me, but theres a circular chain here −− without my public key, you cannot verify the digital signature. You would need my public key in order to authenticate the public key Ive just sent you.
Certificates solve this problem by having a well−known entity called a certificate authority, or CA verify the public key that is being sent to you. A certificate can give you the assurance that the public key in the
certificate does indeed belong to the entity that the certificate authority says it does. However, the certificate only validates the public key it contains: just because Fred sends you his public key in a valid certificate does
not mean that Fred is to be trusted; it only means that the public key in question does in fact belong to Fred.
In practice, the key may not belong to Fred at all; certificate authorities have different levels at which they assess the identity of the entity named in the certificate. Some of these levels are very stringent and require the
CA to do an extensive verification that Fred is who he says he is. Other levels are not stringent at all, and if Fred can produce a few dollars and a credit card, he is assumed to be Fred. Hence, one of the steps in the
process of deciding whether or not to trust the entity named in the certificate includes the level at which the certificate authority generated the certificate. Each certificate authority varies in its approach to validating
identities, and each publishes its approach to help you understand the potential risks involved in accepting such a certificate.
A certificate contains three pieces of information as shown in Figure 9−2: The name of the entity for whom the certificate has been issued. This entity is referred to as the
subject of the certificate. •
The public key associated with the subject. •
A digital signature that verifies the information in the certificate. The certificate is signed by the issuer of the certificate.
•
Figure 9−2. Logical representation of a certificate
Because the certificate carries a digital signature of the certificate authority, we can verify that digital signature −− and if the verification succeeds, we can be assured that the public key in the certificate does in
fact belong to the entity the certificate claims subject to the level at which the CA verified the subject.
We still have a bootstrapping problem here −− how do we obtain the public key of the certificate authority? We could have a certificate that contains the public key of the certificate authority, but who is going to
authenticate that certificate?
This bootstrapping problem is one reason why key management see Chapter 10 is such a hard topic. Most Java implementations solve this problem by providing the public keys for certain well−known certificate
authorities. This has worked well in practice, though it clearly is not an airtight solution especially when the software is downloaded from some site on the Internet −− theoretically, the certificates that come with the
software could be tampered with as they are in transit. Although there are various proposals to strengthen this model, for now we will assume that the certificate of at least one well−known certificate authority is delivered
along with the Java application. This situation allows me to send you a certificate containing my public key; if the certificate is signed by a certificate authority you know about, you are assured that the public key actually
belongs to me. Java 2, version 1.3 comes with 10 certificates of various authorities, which well discuss further in Chapter 10.
There are many well−known certificate authorities −− and therein lies another problem. I may send you a certificate that is signed by the United States Post Office, but that certificate authority may not be one of the
certificate authorities you recognize. Simply sending a public key in a certificate does not mean that the recipient of the public key will accept it. A more important implication of this is that a key management
system needs to be prepared to assign multiple certificates to a particular individual, potentially one from each of several certificate authorities.
Another implication of this profusion of certificate authorities is that certificates are often supplied as a chain. Lets say that you have the certificate of the U.S. Post Office certificate authority, and I want to send you my
certificate that has been generated by the Acme Certificate company. In order for you to accept this certificate, I must send you a chain of certificates: my certificate certified by the Acme Certificate company, and a
certificate for the Acme Certificate company certified by the U.S. Post Office. This chain of certificates may be arbitrarily long.
The last certificate in this chain −− that is, the public key for a certificate authority −− is stored in a certificate that is self−signed: the certificate authority has signed the certificate that contains its own public key.
Self−signed certificates tend to crop up frequently in the Java world as well since the tools that come with the SDK will create self−signed certificates. The certificates are intended to be submitted to a certificate authority
who will then return a CA−signed certificate. But theres no reason why the certificate itself cant be used as a valid certificate. Whether or not you want to accept a self−signed certificate is up to you, but it obviously
carries certain risks.
Finally, for all this talk of certificates, you have to consider whether or not they are actually necessary to support your application. If youll generally be receiving signed items from people you do not know e.g., a
signed jar file from a web site, then they are absolutely necessary. On the other hand, large−scale computer installations often consider using certificates to authenticate and validate their employees; this results in a
computer system that has much better internal security than one that relies solely on passwords. However, the security does not stem from the certificate itself but from the use of public key cryptography. The computer
installation can achieve the same level of security without using a certificate infrastructure.
Consider the security necessary to support XYZ Corporations payroll application. When an employee wants to view her payroll statements, she must submit a digitally signed request to do so. Hence, XYZ should
distribute to each employee a private key to be used to create the digital signature. XYZ can also store the employees public keys in a database; when a request comes that claims to be from a particular employee, the
payroll server can simply examine the database to obtain that employees public key and verify the signature. No certificate is required in this case −− and in general, no certificate is required when the recipient of the
digital signature is already known to have the public key of the entity that signed the data. For applications within a corporation, this is almost always the case.
We issue this caveat about certificates being necessary because certificate support in Java is not fully complete −− while it is possible to set up your own certificate authority to distribute the certificates for your
company, its very hard to write the necessary code to do that in Java. And, frankly, managing certificates is hard. Hence, well focus our discussion of the certificate API on accepting i.e., validating existing
certificates.
Certificate: Class or Interface?
Theres an unfortunate ambiguity in Javas use of the term certificate. In Java 1.1, an interface called
java.security.Certificate was introduced and used by the
javakey utility and
by the appletviewer
when they used signed classes. The Certificate
interface was implemented by platform−specific classes.
In Java 2, there is a new class called java.security.cert.Certificate
. This class is the preferred class for all interactions with certificates and is used by the utilities provided with the
Java 2 platform. The java.security.Certificate
interface has been deprecated in Java 2.
In JSSE, there is yet another type of certificate: javax.security.cert.Certificate
. These certificates are essentially equivalent to the standard Java 2 certificates; well explore them a
little more in Chapter 14. One problem where this manifests itself is with
import statements. If you import the following
packages:
import java.security.; import java.security.cert.;
the compiler will be unable to reconcile the definition of Certificate
. When dealing with certificates, youll either need to refer to them by their fully qualified name or only import those
classes in the security package that you explicitly need. In the main text of this book, whenever we talk about a certificate object without qualifying its
package name, we mean an instance of the java.security.cert.Certificate
class or one of its subclasses. Except for some examples in Appendix C, we will not show usage of the
Certificate interface.
9.4.1 The Certificate Class
There are many formats that a certificate can take depending on the cryptographic algorithms used to produce the certificate. Hence, the Java API abstracts the generic notion of a certificate with the
Certificate class
java.security.cert.Certificate :
public abstract class Certificate Provide the necessary and very basic operations to support a certificate.
Like many classes in the Java security package, the Certificate
class is abstract; it relies upon application−specific classes to provide its implementation. In the case of the SDK, there are classes in the
sun package that implement certain certificate formats but more about that in just a bit.
There are three essential operations that you can perform upon a certificate: public abstract byte[] getEncoded
Return a byte array of the certificate. All certificates must have a format in which they may be transmitted as a series of bytes, but the details of this encoding format are specific to the type of the
certificate. If the encoding cannot be generated, a CertificateEncodingException
is thrown.
public abstract void verifyPublicKey pk public abstract void verifyPublicKey pk, String provider
Verify that the certificate is valid. In order to verify a certificate, you must have the public key of the certificate authority that issued it; a valid certificate is one in which the signature of the certificate
authority is valid. A valid certificate does not imply anything about the trustworthiness of the certificate authority or the subject to which the certificate belongs; it merely means that the signature
in the certificate is valid for the supplied public key. If the certificate is invalid, this method throws a
CertificateException .
The signature is verified according to the digital signature details well examine in Chapter 12. The process of creating an object to verify the digital signature as well as the actual verification of the
signature may throw a NoSuchProviderException
, a NoSuchAlgorithmException
, an InvalidKeyException
, or a SignatureException
. public abstract PublicKey getPublicKey
Extract the public key from the certificate −− that is, the key that belongs to the subject the certificate vouches for.