The CipherInputStream Class Cipher Streams

key exchange and encryption algorithms it supports, and if you communicate only between JSSE servers and clients, you can use DSA keys. However, most browsers understand only RSA−based algorithms, so if youre writing a server that a browser will talk to, you need an RSA key. In the examples in Chapter 10, we created a keystore with an RSA key. Well use that keystore for the examples in this chapter, and well export the certificate from that keystore to use as the truststore. Here are the steps to do that: Create an RSA key for the keystore. See Chapter 10 for information on the genkey option to keytool to do this. You can get a CA−issued certificate for this key if you want, but the examples in this chapter will work with the default self−signed certificate. 1. Export the RSA certificate without the private key: piccolo keytool −export −alias sdo −file test.cer Enter keystore password: Certificate stored in file test.cer 2. Import the RSA certificate into a new file the truststore. This allows us to recognize the issuer of the certificate as a valid CA. If you got a CA−issued certificate, you can use the trustcacerts option to accept the certificate automatically. Were storing the truststore in HOME.truststore ; on Microsoft Windows, you might substitute C:\WINDOWS\ .truststore or any other file you like. Heres how to import the certificate: piccolo keytool −import −alias test −keystore HOME.truststore −file test.cer Enter keystore password: Owner: CN=Test Certificate, OU=My Test Organization, O=Me, Inc., L=NY, ST=NY, C=US Issuer: CN=Test Certificate, OU=My Test Organization, O=Me, Inc., L=NY, ST=NY, C=US Serial number: 39f3a2f3 Valid from: Sun Oct 22 22:31:15 EDT 2000 until: Sat Jan 20 21:31:15 EST 2001 Certificate fingerprints: MD5: 5E:B0:1C:D5:F6:2E:36:BF:F8:00:AA:4B:66:28:DE:DD SHA1: 28:B7:83:D2:0E:95:1D:EE:C3:D7:A9:D4:D5:1E:0E:82:E0:E9:F3:8D Trust this certificate? [no]: yes Certificate was added to keystore 3. At this point, we have two files. The keystore file contains the private key and a certificate that vouches for our identity; well use that as the servers keystore. The truststore file contains just the certificate; well use it as the clients truststore.

14.1.2 JSSE Certificates

JSSE defines yet another certificate class, javax.security.cert.Certificate . This class is not related either to the java.security.cert.Certificate class that weve used in all our previous examples or to the deprecated java.security.Certificate interface. Since JSSE is designed to run on Personal Java implementations, for which the java.security package is optional, it cannot rely on classes from that package and must define its own certificate class. Suns reference implementation of JSSE, however, uses the java.security.cert.Certificate class internally, so it cannot run on versions of PersonalJava that do not supply the optional java.security package. This does not prevent third parties from implementing JSSE independent of the java.security package and providing those implementations with more limited PersonalJava packages. It does, however, limit the environments in which you can use Suns JSSE implementation. The APIs of the java.security.cert.Certificate and javax.security.cert.Certificate classes are identical. However, there are no facilities to convert easily between the two classes; you must get the encoded bytes from the javax.security.cert.Certificate and feed them through a java.security.cert.CertificateFactory object. In addition, JSSE defines a javax.security.cert.X509Certificate class that is identical to the java.security.cert.X509Certificate class, although again it is unrelated to that class in the Java class hierarchy. Handling JSSE certificates often requires that you parse the distinguished name DN held in the certificate. To make that easier, well use this class in our examples: package javasec.samples.ch14; Store an X500 Name and extract its components on demand public class X500Name { private String CN, OU, O, L, ST, C; private String name; private char nameChar[]; public X500NameString s { if s == null throw new IllegalArgumentExceptionName cant be null; name = s; } public String getCN { if CN == null CN = parseCN=; return CN; } public String getOU { if OU == null OU = parseOU=; return OU; } public String getO { if O == null O = parseO=; return O; } public String getL { if L == null L = parseL=; return L; } public String getST { if ST == null ST = parseST=; return ST; } public String getC { if C == null C = parseC=; return C; }