Figure 99. Installing the Java Runtime Environment and Java Plug-in
If you install the Java 2 SDK while the JRE box is checked, you will have in
fact two JREs on your system: one is installed with the SDK and the other is a
separate JRE. You can uncheck the option to install the JRE at the very
beginning of the install process but later you cannot do that.
On Windows systems, Java 2 SDK, Standard Edition, V1.2.x installs by
default in the C:\jdk1.2.x directory and JRE in the directory
C:\Program Files\JavaSoft\JRE\1.2. If you keep the default settings, you will
find two pairs of the security configuration files: one in the directory
C:\jdk1.2.x \jre\lib\security and the other in the directory
C:\Program Files\JavaSoft\JRE\1.2\lib\security. The configuration files which
are effective are in the second directory. In this case, the value of the variable
java.home is C:\Program Files\JavaSoft\JRE\1.2, as demonstrated in
Appendix A, “Getting Internal System Properties” on page 641.
However, if you uncheck the option to install the JRE at the beginning, you get
only one set of security configuration files. The value of the variable
java.home in this case is C:\jdk1.2.x\jre and the configuration files are located
in C:\jdk1.2.x\jre\lib\security. Interestingly, if you do not uncheck the option at
226
Java 2 Network Security
the beginning, and later on, during the JRE installation, you change the
installation directory of the JRE to C:\jdk1.2.x \jre, then the previous files are
overwritten. In such a case the installation routine does not install the JRE
again and the value of java.home is C:\jdk1.2.x\jre, which is the JRE
development directory.
The value of java.home takes effect for all the Java programs you run on your
system, including the applets you run in a Web browser that make use of the
Java Plug-in (see Chapter 11., “The Java Plug-In” on page 359); the system
uses the value of that variable to search for system libraries and configuration
files. However, for all the development tools, such as the Java compiler and
the Applet Viewer, the system always considers java.home as C:\jdk1.2.x \jre,
irrespective of whether JRE is installed again or not. This is because test
tools are used for development only. So, in this way, Java helps you separate
the development environment from the run-time environment. This is
demonstrated by the following applet:
import java.applet.*;
import java.awt.Graphics;
public class PropertyApplet extends Applet
{
public void paint(Graphics g)
{
try
{
String s1 = System.getProperty("java.home");
String s2 = System.getProperty("user.home");
g.drawString("java.home has the following value: " + s1, 20, 20);
g.drawString("user.home has the following value: " + s2, 20, 40);
}
catch (Exception e)
{
System.out.println("Exception caught" + e.toString());
}
}
}
Figure 100. PropertyApplet.java
This applet is compiled through the command:
javac PropertyApplet.java
We invoke it from within the following HTML page:
Security Configuration Files in the Java 2 SDK
227
PropertyApplet AppletPropertyApplet Applet
Figure 101. PropertyApplet.html
Next, we invoke this HTML page with the Java 2 SDK Applet Viewer:
appletviewer PropertyApplet.html
In order for the command above to work without throwing any exception, it is
necessary to grant the Java class PropertyApplet, residing in the directory
D:\itso\ch08, the permission to read the Java system properties java.home
and user.home. This is done by adding the following lines to one of the
current policy files, as we will see in 8.4, “Security Policy Files” on page 242:
grant codeBase "file:/D:/itso/ch08/" {
permission java.util.PropertyPermission "java.home", "read";
permission java.util.PropertyPermission "user.home", "read";
};
The appletviewer command brings up the following Applet Viewer window:
228
Java 2 Network Security
Figure 102. PropertyApplet Running
This demonstrates that for a development tool, such as the Applet Viewer, the
java.home directory changes to become the JRE development directory, while
another system property, such as user.home, still has the same value.
Notice that, whenever you have two JRE environments installed on your
machine, you need to be very careful and must know where your library and
configuration files are being picked up from. For example when you compile a
Java program using the command:
javac MyClass.java
then the core Java classes and the extensions are picked up from the JRE
development directory (typically C:\jdk1.2.x\jre) and its subdirectories.
However, when you run the program with:
java MyClass
then they are picked up from the separate JRE run-time directory (typically
C:\Program Files\JavaSoft\JRE\1.2) and its subdirectories. The same holds
true for the security and policy files, which are the security configuration files.
When the JRE is installed, a copy of the java executable file (java.exe on
Windows systems) is also put in a location that is on the operating system’s
default system Path. For example, on a Windows NT system, it is typically put
in C:\WINNT\system32. Hence, when you install the Java 2 SDK, you will be
able to run the java command without setting the Path variable. However, to
run the javac command, you will have to include the appropriate path to the
javac executable file (javac.exe on Windows systems) in the Path variable. All
SDK development tools, including the javac compiler, are installed in the
same directory, typically C:\jdk1.2.x\bin, on Windows systems.
Security Configuration Files in the Java 2 SDK
229
How Does the System Know the Value of java.home?
You are probably wondering how the system can know the value of the
java.home property. If you install Java 2 SDK, Standard Edition, V1.2 on
AIX and you run the program GetProperty shown in A.2, “Program
GetProperty” on page 644 to find out the value of java.home, you see the
following output:
property value is: J1.2/bin/..
This means that to define java.home, Java finds the directory where the
Java executable files are and then goes one level up: that is the java home
directory. This, at least, seems to happen on AIX. We repeat the same
experiment on Windows NT.
If we move all the Java executables to the D:\itso\bin directory, java.home
becomes D:\itso, as the following output demonstrates:
java.home property value is: D:\itso
If we put them in D:\ all programs return an error as there is no directory
one level up from the root directory.
Note that in order to verify the java.home directory when moving the
executables, the Path variable must be manually set to include the new
directory where the executables are and the boot class path must be
specified on the command line using the -Xbootclasspath option.
In the rest of this section we describe the two security configuration files of
the Java system. However, before examining them, we first need to introduce
the concept of a keystore.
8.2 Keystores
A keystore is a database of private keys and their associated certificates or
certificate chains, which authenticate the corresponding public keys.
The default keystore implementation, provided by Sun Microsystems, is a flat
file, utilizing a proprietary keystore type or format, named Java Keystore
(JKS). This format protects the integrity of the entire keystore with a keystore
password. A hash value of the entire keystore is used to protect the keystore
from alteration. Each private key in the keystore is also protected with a
separate password (though this password may be identical to the keystore
password). In different keystore implementations that can make use of
230
Java 2 Network Security
encryption, such as the keystore implementation that comes with JCE 1.2
(see Point 2 on page 492), private keys can be stored encrypted using one of
the encryption algorithms provided.
Notice that a KeyStore class is provided in the package java.security. It
supplies methods to access and modify the information in the keystores (see
10.1.6, “Key Management” on page 305).
On a Windows NT system, the keystore is created by default with the keytool
command as the file .keystore in the directory ${user.home}. It is possible to
change both the implementation and the location of the keystore that comes
by default with the Java 2 SDK installation, but the system must be aware of
what implementation and location have been selected:
• The implementation of the keystore is specified, as we are going to see, in
the security properties file, defined by the value of the property named
keystore.type.
• The location of the keystore is specified in the policy file, defined by the
keystore URL entry.
If you so desire, you can create a new keystore implementation. You might
want to do so to, say, store keys and certificates in a database. Then you
need to refer to your own keystore implementation in the security properties
file and to the location of the keystore in the policy file.
In a keystore you can store your own certificates or certificates of CAs and
trusted entities. As we have said, Java 2 provides the keytool command line
utility for storing your private keys and viewing or listing public information
about a certificate in a JKS keystore. Since a keystore is password-protected,
you need to enter a password to access the private information stored in the
keystore. Each private key may also be protected by a separate password
which also needs to be provided by the user.
Notice that public information can be accessed without the password.
However, in that case, as the keytool utility is unable to verify the integrity of
the keystore, a warning message is displayed on the screen, as shown here:
***************** WARNING WARNING WARNING *****************
* The integrity of the information stored in your keystore *
* has NOT been verified! In order to verify its integrity, *
* you must provide your keystore password.
*
***************** WARNING WARNING WARNING *****************
Security Configuration Files in the Java 2 SDK
231
You will notice that if you register the public information of a certificate as
trusted and then try to run an applet signed by that certificate, the JVM
automatically retrieves the public key from the keystore, without your
intervention and without asking for the keystore password. The reason for this
is that all public information, such as public key and certificate, is stored
unencrypted in the keystore, and only the private key is stored
password-encrypted, so that it is protected from unauthorized users. The
keystore password is used for an integrity check only, so you are prompted to
verify that the keystore has not been tampered with.
A demonstration of this can be obtained in the following way. When you open
the keystore with a text editor, amidst all the junk, you can see the value of a
certificate you know existed in the keystore in plain text:
keyname
organization unit
state
city
country
organization
start date
end date
first and last name
Figure 103. On Opening a Keystore with a Text Editor
Notice also that all keys or certificates stored in the keystore are identified by
aliases.
Users can have as many keystores as they wish. Users can create additional
keystores if they want to:
1. Generate a public-private key pair for themselves.
232
Java 2 Network Security
2. Sign a code with their private key and export their certificates to send to
others for verification along with the signed code.
3. Import others’ certificates to verify signatures.
4. Create a certificate request to be signed by a certification authority (CA).
All these activities are facilitated by the keytool command line utility. Notice
that each different keystore can be protected with a different password.
8.2.1 The Certificates KeyStore File cacerts
The cacerts file is a system-wide keystore for storing trusted CA certificates.
It is implemented in the JKS format, is located in the
${java.home}${/}lib${/}security directory and can be manipulated with the
keytool command line utility.
Currently, the cacerts file ships with five VeriSign root CA certificates. You can
view these certificates using the -list command associated with the keytool
utility:
keytool -list -keystore cacerts
The output of this command is shown in the following figure:
Keystore type: jks
Keystore provider: SUN
Your keystore contains 5 entries:
verisignclass3ca, Mon Jun 29 13:05:51 EDT 1998,
Certificate fingerprint (MD5):
78:2A:02:DF:DB:2E:14:D5:A7:5F:0A:DF:B6:8E:9C:5D
verisignclass1ca, Mon Jun 29 13:06:17 EDT 1998,
Certificate fingerprint (MD5):
51:86:E8:1F:BC:B1:C3:71:B5:18:10:DB:5F:DC:F6:20
verisignserverca, Mon Jun 29 13:07:34 EDT 1998,
Certificate fingerprint (MD5):
74:7B:82:03:43:F0:00:9E:6B:B3:EC:47:BF:85:A5:93
verisignclass4ca, Mon Jun 29 13:06:57 EDT 1998,
Certificate fingerprint (MD5):
1B:D1:AD:17:8B:7F:22:13:24:F5:26:E2:5D:4E:B9:10
verisignclass2ca, Mon Jun 29 13:06:39 EDT 1998,
Certificate fingerprint (MD5):
EC:40:7D:2B:76:52:67:05:2C:EA:F2:3A:4F:65:F0:D8
trustedCertEntry,
trustedCertEntry,
trustedCertEntry,
trustedCertEntry,
trustedCertEntry,
Figure 104. Default CA Certificates in the Java 2 Platform
Security Configuration Files in the Java 2 SDK
233
On launching this command you will be asked for the password. However, a
password is not mandatory to display the contents of a keystore; if you do not
enter the right password, the output shown in the figure above is displayed
anyway, but you will be informed that the integrity of the information stored in
the keystore has not been verified. On the contrary, you will not be allowed to
import a new certificate in the keystore file if you do not enter the exact
password. By default, the initial password is changeit. As the name itself
suggests, it is recommended you change the default password, as this
keystore is very important for the simple reason that it contains the
certificates of the CAs that are considered trusted. A keystore password can
be changed using the -storepasswd command associated with the keytool
command line utility (see 9.1.3, “Commands and Options Associated with
keytool” on page 262).
Since CAs are entities that are trusted by users for signing and issuing
certificates to other entities, the cacerts file should be managed only by
system administrators. With the keytool utility, it is possible to add new CA
certificates or remove old CA certificates from the cacerts file. Utmost care
should be taken while importing any trusted certificate into the cacerts
keystore, as it should only contain certificates of the CAs that the system
administrators trust.
8.3 The Security Properties File, java.security
This is a configuration file in which you set the Java security properties for the
system. These security properties are used by classes in the java.security
package. The following figure shows the default properties file installed with
Java 2 SDK, Standard Edition, V1.2.1, except for the fact that the comments
that explain each entry have been removed here:
security.provider.1=sun.security.provider.Sun
policy.provider=sun.security.provider.PolicyFile
policy.url.1=file:${java.home}/lib/security/java.policy
policy.url.2=file:${user.home}/.java.policy
policy.expandProperties=true
policy.allowSystemProperty=true
policy.ignoreIdentityScope=false
keystore.type=jks
system.scope=sun.security.provider.IdentityDatabase
package.access=sun.
#package.definition=
Figure 105. Default Security Properties File
234
Java 2 Network Security
As we have said, the directory where this file is installed is
${java.home}${/}lib${/}security, and a copy of it is found also in the JRE
development directory for use with the development tools.
The java.security file, amidst all the comments and explanations, contains
important directives, which are all of the form:
property_variable=value
Notice that by default the last entry is commented out.
In the following list we explain all the entries of the default security properties
file:
• Security provider
The first entry specifies the cryptography package providers, their
locations, and their precedence orders. The term provider refers to a
package or set of packages that supply a concrete implementation of a
subset of the cryptography aspects of the Java Security API. A provider
may, for example, implement one or more digital signature algorithms or
message digest algorithms.
There must be at least one provider specification in java.security. If an
alternative provider has to be added, it must be specified in the security
properties file as:
security.provider.n=className
This adds the provider with the preference order n. The provider order is
1-based. If an implementation is supplied by multiple providers, the
implementation of the provider with the higher preference (that is, lower
serial number n) is chosen. This means that the JVM looks for the
implementation required in the first provider. If it is found, it stops and uses
that; otherwise, it looks in the next provider, and continues until it gets the
implementation.
className must specify the subclass of the java.security.Provider abstract
class whose constructor sets the values of various properties that are
required for the Java security API to look up the algorithms or other
facilities implemented by the provider.
The Provider class has methods for accessing the provider name, version
number, and other information about the implementations of the
algorithms for key generation, conversion and management facilities,
signature generation, and message digest generation.
Provider subclasses statically registered through the security properties
file are instantiated when the system is initialized. Providers may also be
Security Configuration Files in the Java 2 SDK
235
registered dynamically. To do so, you should call either the addProvider()
or insertProviderAt() static methods in the java.security.Security class.
However, such a configuration is not persistent and can only be done by
trusted programs. This may be done if only specific applications need a
particular provider. Note that by trusted programs we mean applications
that have been granted a specific SecurityPermission by the user. See 8.4,
“Security Policy Files” on page 242 and 10.7, “The Permission Classes” on
page 339 for more details.
The default provider that comes standard with the Java 2 SDK is called
SUN, and its Provider subclass, named Sun, appears in the
sun.security.provider package. The SUN provider offers:
• An implementation of the Digital Signature Algorithm (DSA)
Signature algorithms are used to create a signature of a particular file
using the message digest and the private key of the signer.
• An implementation of the MD5 and Secure Hash Algorithm (SHA)-1
message digest algorithms
Message digest algorithms are used to create the message digests of
files using the file itself and the constant chaining variable defined in
the digest algorithm.
• A DSA key pair generator for generating a pair of public and private
keys suitable for the DSA algorithm
• A DSA algorithm parameter generator
• A DSA algorithm parameter manager
• A DSA key factory providing bi-directional conversions between
opaque DSA private and public key objects and their underlying key
material
• An implementation of the proprietary SHA1PRNG pseudo-random
number generation algorithm
• A certificate factory for X.509 certificates and certificate revocation
Lists (CRLs)
• The JKS keystore implementation for the proprietary keystore type
• Policy provider
The second entry in the security policy file specifies the class to
instantiate as the system policy. This is the name of the class that will be
used as the Policy object, in order to determine which permissions are
available for code from various sources. The code source includes the
236
Java 2 Network Security