Chapter 25. Java Security

Java Security

The term “security” means controlling the resources of your computer system: the files, screen, peripherals, and CPU cycles. Even on a single-user PC, this is an issue because a Windows virus can destroy your data, or the system can be hijacked from over the network. Some form of security check is particularly needed with anything that is downloaded and executed automatically on your behalf. Just by browsing a web page, embedded applets are sent over and executed on your system. Without a security check an applet could, either through maliciousness or poor programming, corrupt your files or transmit the contents to points unknown.

Viruses are already too prevalent in the PC world. Viruses are today commonly spread today through MS-Word documents by using an “execute macros on start-up” feature. Windows 9x has essentially no security. In October 2001, a Gartner Group analyst advised sites that value security not to use Microsoft’s IIS web server. The ActiveX framework has identification through code signing, but no security in terms of resource access permission. A malicious or even simply buggy program can access your entire system, even if you wanted only to give it read access to one specific temp directory. This security deficiency makes ActiveX (or OLE, or DCOM, or DNA, .NET etc.; whatever is Microsoft’s current marketing name for its preferred method of executing programs on a remote computer) unsuitable for use across the Internet.

The point is that security on desktop computers is far from where it should be, and there are large, real costs associated with that. Any new technology needs to help move the situation back in the right direction, rather than add to the problems.

Java improves on the current situation by defining and supporting several levels of resource access control. Some of Java’s security is user-configurable, and some of it (to avoid a breach of security) is not. Here’s how security has been refined and extended over successive Java releases:

  • All Java releases feature language security (strong typing, no pointer arithmetic, etc.) and runtime type checking of array indexes, casts, references, etc., as well as verification of remotely-loaded bytecode.

  • JDK 1.0.2 runs applets in the sandbox—a restricted environment that denied applets access to client system resources like local files.

  • JDK 1.1 introduced the ability to sign applets, meaning “provide a cryptographic assurance that the applet comes from a source you trust.” Signed applets can run with the same privileges as local applications. All code is still subject to the language and runtime security features, of course.

  • JDK 1.2 (i.e., the Java 2 platform) introduced the really significant security improvements. All code, regardless of whether it is local or remote, an applet or an application, can now be made subject to a security policy that defines how and what it can access. For example, you can give a program write access to a directory, but not read access. The policy can be set by programmers, by systems administrators, or by users.

The security policy is a list of all the possible permissions available for code (read access, write access, which directories, etc.), matched with a list of the various URLs code can come from and the various organizations from which you will accept signed code. You apply aspects of the policy to bundles of classes, called domains. System administrators can put a central security policy in place, and users can customize it for their individual needs.

  • JDK 1.3 introduced a moderate number of minor improvements, such as compatibility with Verisign’s code signing certificates. Several new methods were added to the APIs.

  • JDK 1.4 introduced a small number of quite significant features. Three optional packages (Java Cryptography, Secure Sockets, and Authentication/Authorization Service) were made part of the standard release. Due to import regulations in France, Israel, and Russia preventing their citizens from having strong encryption software, the system ships with encryption of limited strength.

Finally, JDK 1.4 offers a new library that implements the Generic Security Services API, allowing Java programmers easy access to Kerberos V5 and other security mechanisms.

The Parts of Java Security. As delivered with JDK 1.4, Java security provides these features:

  • A permissions and access control framework for code at runtime. A full example of how to use this framework appears in this chapter.

    The features are in package java.security and its subpackages.

  • A set of classes and tools for code signatures. A “signature” is a digital stamp of authenticity that can be applied to a file. The signature is different for each file, and it guarantees that the bytes in the file have not changed since they were signed. The signature is generated from a key which you keep private (so no one else can forge your signature), and it can be confirmed by anyone using a key that you publish. Examples of digital signature algorithms are DSA or RSA with MD5. A full example of how to sign code is given in this chapter.

    The features are in package java.security and its subpackages.

  • A set of classes and tools for certificate management. A “certificate” is a digitally signed statement from one organization or person that you trust, blessing or vouching for the public key of some other organization or person. Certificates are specified by the X.509 v3 standard, or the PGP standard.

    The features are in package java.security.cert

  • A set of classes to encrypt and decrypt to and from Streams. You get an instance of a Cipher by calling javax.crypto.Cipher.getInstance(“what”), giving a string argument that specifies the cipher you want. You then construct a java.io.OutputStream, and layer a javax.crypto.CipherOutputStream on it, giving the Cipher object as an argument. Writes to the CipherOutputStream will be encrypted, and the results can be read back in through a CipherInputStream.

    The features are in package javax.crypto and its subpackages.

  • A set of packages to authorize and authenticate users. The classes in these packages can be used to reliably and securely identify who is attempting to execute some Java code. The authentication can be done by Kerberos, or the Java Naming and Directory service, or by an operating system feature.

    The features are in packages com.sun.security, javax.security, and their subpackages.

  • A set of classes to support message authentication codes (MAC). A MAC gives a way to check the integrity of information stored or sent over an insecure channel. It does not keep the bits secret; it answers the question “have these bits been changed at all?” It is like a very reliable parity code. MACs are a general case of code signatures. Typically, MACs are used between two parties to validate the information arriving at one end is the same as it was when it left the other. Java uses two well-known cryptographic hash functions to support MAC: MD5 and SHA-1.

    The features are in package javax.crypto and its subpackages.

  • A set of classes to support secure sockets layer networking (SSL). Secure Socket Extension (JSSE) is a set of Java packages that enable secure Internet communications. It implements a Java version of SSL (Secure Sockets Layer) and TLS (Transport Layer Security) protocols and includes functionality for data encryption, server authentication, message integrity, and optional client authentication. Using JSSE, developers can securely send data between a client and a server running any application protocol (such as HTTP, Telnet, NNTP, and FTP) over TCP/IP.

The features are in package javax.net and its subpackages.

The encryption technology used to be shipped separately in an optional extension package only available in North America, due to U.S. law which made it a crime to export certain kinds of software. That law didn’t prevent anyone anywhere from getting encryption technology, but it did mean they could not get it from American companies.

As an aside, the U.S. government has a hate/hate relationship with encryption software. At the drop of a hat, the director of the FBI will make speeches urging strict restrictions on crypto software (one proposal involved requiring you to give the government your secret decoding key). The proposals are generally accompanied by vague handwaving about crime and terrorism. But the handwaving is not borne out by facts. The Center for Democracy and Technology did a study of wiretaps and encryption, and discovered that of 1,190 wiretaps that were authorized in the year 2000, in 20 cases they came across some encryption, and the government was able to decode every one. A similar study of steganography (hiding messages in other files) by two University of Michigan researchers in 2001 looked at more than 2 million files on the Internet and found no coded messages at all.

The problem for the U.S. government is not that it cannot break your coded messages. The problem seems to be that if everyone uses encryption routinely, it becomes more difficult to do traffic analysis or pay special attention to encoded messages. In any event, the encryption software laws have now been relaxed a little, and JDK 1.4 now includes encryption tools that can be exported without restriction from the USA.

In this chapter we will specifically look at the sandbox, code signing, and the security manager (which is how the security policy is applied).

The Sandbox

Code Signing

An earlier chapter showed how to put Java applets into jars. The next step is to describe how jars can be used to convey the notion that the code is trusted. Since an applet can be downloaded from anywhere on the net just by browsing a URL, the default security model needs to be very strict. JDK 1.1 introduced support for signing an applet, which gives the browser the opportunity to identify who wrote the applet and then choose to let the applet access all system resources. JDK 1.2 lets you configure more precisely the resources that can be accessed by signed code.

Signing some code in a jar file is like signing a bank check. It means labeling it with a tamper-proof identifying mark saying where it came from. Don’t we already know this? Doesn’t it come from the URL we are browsing? The answer is that we are not sure enough to give our system away to the applet.

Applets start running by virtue of visiting a page; there need not be any visible indication that the page contains an applet. Secondly, although an applet is hosted on a page, it is not necessarily located on that page. The CODEBASE applet tag can point to a URL anywhere else on the net. Finally, with enough effort, it is possible to spoof (masquerade as) web servers. If the stakes are high enough people could do this to make a malicious or fraudulent applet appear to come from mother.teresa.org.

Signed applets have more privileges.

Figure 25-1. Signed applets have more privileges.

We can write our signature on a check because it is a physical piece of paper. For an applet in a jar file, we add an extra file saying what the origin is. Obviously, it wouldn’t be good enough just to put an ASCII text file in there saying, “Software from Honest Software Corporation,” since the drug-peddling, code-encrypting, porno-terrorists that the FBI says are all over the Internet could easily forge that file on their own applets.

Instead, we use computer encryption to sign a file. Here is a summary of the basic steps:

  1. Do all the one-time preparation necessary to set yourself up for encrypting files. The preparation consists of generating your code keys, registering them with the keystore database, getting yourself a digitally-signed certificate attesting to who you are, and a couple of other things. You will use the Java keytool utility program for all this.

  2. Put all the files that make up the applet into a jar file. We have already seen how to do this in the previous section.

  3. Sign the jar file. The jarsigner signing utility looks up your secret code in the keystore database and runs it over a hash of the jar file and the directives file. Then, it adds the coded result to the jar. Anyone can look at it, and anyone could change it, but if they do, the results won’t match the hash value that was generated using your secret code, and the tampering will be obvious.

  4. Export the public key certificate that you generated in step 1. People who wish to check your signature before running the code must import your certificate into their own keystore.

  5. Put the signed applet jar file on your web page, and let people have at it.

This process makes the applet trusted. The longest part of the process is the one-time setup.

The Security Manager

All browsers install a security manager, and you can install one on your applications too. It’s called by the runtime. Look at this code in the runtime library to create a FileInputStream:

public FileInputStream(String name) throws FileNotFoundException {
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
       security.checkRead(name);
   }
   fd = new FileDescriptor();
   open(name);
} 

Before it does anything else, the code gets the SecurityManager object for the system. If there isn’t one (the reference is null), it goes ahead. However, if someone has created a SecurityManager, then its checkRead() method is called.

The checkRead() method will judge whether this operation is permitted or not. Perhaps it looks to see if the program is trying to read from one of several directories that it is allowed to access. Perhaps the program is only allowed to read files with a certain name, or that are newer than some date. There will be some application-specific protocol for judging whether access is permitted or not.

If it is permitted, the method does its work and returns without a problem. If the file access is not permitted (you’re an ordinary applet that was just downloaded, for example), a SecurityException is thrown, tossing you out of the FileInputStream constructor before the object creation completes.

The SecurityManager is a built-in class in package java.lang with about a dozen methods, each of which checks access to a particular resource: threads, properties, socket connections, reading a file, and so on.

The java.lang.SecurityManager class contains the following public methods:

public class java.lang.SecurityManager extends java.lang.Object {
     public java.lang.SecurityManager();
     public void checkAccept(java.lang.String, int);
     public void checkAccess(java.lang.Thread);
     public void checkAccess(java.lang.ThreadGroup);
     public void checkAwtEventQueueAccess();
     public void checkConnect(java.lang.String, int);
     public void checkConnect(java.lang.String, int, Object);
     public void checkCreateClassLoader();
     public void checkDelete(java.lang.String);
     public void checkExec(java.lang.String);
     public void checkExit(int);
     public void checkLink(java.lang.String);
     public void checkListen(int);
     public void checkMemberAccess(java.lang.Class, int);
     public void checkMulticast(java.net.InetAddress);
     public void checkMulticast(java.net.InetAddress, byte);
     public void checkPackageAccess(java.lang.String);
     public void checkPackageDefinition(java.lang.String);
     public void checkPermission(java.security.Permission);
     public void checkPermission(java.security.Permission, Object);
     public void checkPrintJobAccess();
     public void checkPropertiesAccess();
     public void checkPropertyAccess(java.lang.String);
     public void checkRead(java.io.FileDescriptor);
     public void checkRead(java.lang.String);
     public void checkRead(java.lang.String, java.lang.Object);
     public void checkSecurityAccess(java.lang.String);
     public void checkSetFactory();
     public void checkSystemClipboardAccess();
     public boolean checkTopLevelWindow(java.lang.Object);
     public void checkWrite(java.io.FileDescriptor);
     public void checkWrite(java.lang.String);
     public boolean getInCheck();
     public java.lang.Object getSecurityContext();
     public java.lang.ThreadGroup getThreadGroup();
} 

The methods scrutinize some specific form of resource access. So checkRead(java.io.FileDescriptor) will return normally if a read may be done using this file descriptor, and throw an exception if it should not. The three methods, whose names are not self-descriptive, carry out this processing:

checkSetFactory()

This effectively checks whether the caller is allowed to provide his own implementation of certain network-related objects.

getInCheck()

Simply says whether a check is currently taking place.

getSecurityContext()

Returns an implementation-dependent Object which stores enough information about the current execution environment to perform some of the security checks later.

You never call these checking methods; they are called at appropriate times by the Java runtime. The calls are already in place throughout the runtime library. When a Java system first starts executing, the security manager is set to null and the only access restrictions are those imposed by the underlying operating system. In other words, anything goes.

To change the default, you can write your own class that extends SecurityManager and provide new methods to override the parent checking method for the resources you are interested in. The body of each new method contains your algorithm for deciding whether to grant access or not. It will either return or throw a security exception. Returning without throwing an exception means the access is allowed. If you install a new security manager of your own, then every resource not controlled in your new manager is disallowed. Following is an example that allows access to all system properties and nothing else:

class MySecurityManager extends SecurityManager {
     public void checkPropertyAccess(String key) {
          return;
     }
}


public class foo {
     public static void main(String s[]) {
          SecurityManager msm = new MySecurityManager();
          try {
               System.setSecurityManager(msm);
          } catch(Exception e){}
     }
} 

A SecurityManager can be set, at most, once during the lifetime of a Java runtime. There is no way to install a new SecurityManager that includes permission to keep installing new SecurityManagers—it’s a one-shot deal and cannot be replaced, changed, or overridden later on. In an application, you, the programmer, can define the level of security for your program. In an applet, the browser sets the SecurityManager and decides what processes to follow to grant or deny access. Applets must be unable to impose a new security manager.

Different browsers have imposed slightly different SecurityManager policies, and they can take into account whether an applet was loaded from a local file or from browsing over the Internet. Local files only exist on your system because you put them there, so they are presumed to have more privileges. Table 25-1 is a matrix of browser characteristics extracted from the JavaSoft site www.javasoft.com/sfaq.

Table 25-1. Capabilities of an Untrusted Applet

Capabilities

BP/net

BP/local

Av/net

Av/local

Applic

Key:

• BP/net: browser with a Java Plug-in, loading applets over the net

• BP/local: Browser with a Java Plug-in, loading applets from local file system

• Av/net: Appletviewer, loading applets over the net

• Av/local: Appletviewer, loading applets from the local file system

• Applic: Java stand-alone applications

Read or write a file in /home/me with access control list set

no

no

yes

yes

yes

Read the user.name property

no

yes

no

yes

yes

Connect to port on client

no

yes

no

yes

yes

Connect to port on 3rd host

no

yes

no

yes

yes

Load library

no

yes

no

yes

yes

Exit(-1)

no

no

no

yes

yes

Create a pop-up window without a warning

no

yes

no

yes

yes

The restrictions mean that an applet loaded from over the Internet:

  • Can really read and write files if an access control list file permits it, and you run the applet using appletviewer.

  • Cannot make network connections to hosts other than the one it came from.

  • Cannot start a program on your system by using the equivalent of the system() call in C. An application or local applet can do this with the method java.lang.Runtime.exec().

  • Cannot load a library.

  • Cannot execute native code.

The SecurityManager class provides a way to recognize trusted code so we can grant it more capabilities without jeopardizing system security.

Capabilities of an Untrusted Applet

You can configure the Sun appletviewer to read and write files on your local disk by editing the file .hotjava/properties. This file is in your home directory on Unix (note its name starts with a dot, so it is not usually visible when you list the directory). Under Windows, the files is in the root directory of the drive on which you installed Java (the file might be C:.hotjavaproperties). Note that this works for the appletviewer only, not other browsers like Netscape.

Then you can set the acl.read and acl.write properties to point to the files or directories that you will allow applets to read or write. For example, if I add these two lines to my ∼/.hotjava/properties file (or my C:.hotjavaproperties file on Windows), then applets are allowed to read any files in /home/linden or to write to any files in the /tmp directory.

acl.read=/home/linden
acl.write=/tmp 

ACL stands for Access Control List—a mainframe feature for providing fine-grained control of resources like files.

Here’s an applet that you can run under Sun’s appletviewer to confirm this:

// <applet code=show.class  height=100 width=200> </applet>
import java.io.*;
import java.awt.*;
import java.applet.Applet;
public class show extends Applet {

     public void Read() throws IOException {

          DataInputStream dis;
          String s, myFile = "show.java";

          dis = new DataInputStream(new FileInputStream(myFile));
          s = dis.readLine();
          System.out.println("line> "+s);
     }

     public void paint(Graphics g) {
          try {
               Read();
               g.drawString("Success in read", 10, 10);
     }
          catch (SecurityException e) {
               g.drawString("Caught security exception in read", 10, 10);
     }
          catch (IOException ioe) {
               g.drawString("Caught i/o exception in read", 10, 10);
          }
     }
} 

If you need a refresher on the I/O details take a look at Chapter 13. For now, the purpose is to demonstrate that the security manager controls the resources accessed by applets and that file I/O is possible from an applet using the applet-viewer.

Applying the Security Policy

The previous three sections explained how security restrictions are enforced. This section describes how a fine-grained security policy can be set up to specify exactly what the restrictions are and to which code and code signers they apply. The notion of security policies, and the tools to adjust them, has been in Java since JDK 1.2.

The one-sentence summary of Java Security Policy is, “There are a bunch of files outside the Java system that keep a record of the way application and applet classes are grouped together into domains, and the permissions associated with those domains.” The security is carefully tracked by the runtime, so a less-privileged class cannot grab more permissions because it called or was called by a more powerful domain.

The way that permission is granted is by adding an entry to a policy file. Policy files exist in a couple of standard places, and users can create additional ones and specify them as a command-line argument when they start a program. The format of an entry in a policy file is a little tricky; it resembles statements in a programming language. At least the entries are in ASCII, not binary, so you don’t have to use the policytool provided, and can just edit the file if you prefer. If this was designed today, the configuration would be specified in XML. Instead. it uses a pseudo-Java syntax.

Each grant entry in the policy file is of the following format, where the leading grant is a reserved word that signifies the beginning of a new entry. Optional items appear in brackets. The keyword permission is another reserved word that marks the beginning of a new permission in the entry. Each entry grants a set of permissions to the specified code source.

grant [SignedBy "signer_names"] [, CodeBase "URL"] {

permission permission_class_name
  ["target_name"]   [,"action"]   [,SignedBy "signer_names"];

    // there may be a series of permission statements
}; 

Here is an example of a pretty minimal policy file. We will use this in a later chapter to grant a program the ability to connect and accept connections on sockets:

grant  {
      permission java.net.SocketPermission "*", "connect";
      permission java.net.SocketPermission "*", "accept";
}; 

We put that text into a file called “permit,” and then start the program mentioning the permission filename like this:

java -Djava.security.policy=permit  MySocketProgram 

Here is another example policy file, where I say that I will grant file read and write permission in the /tmp directory or any subdirectory of it to all applets that originate from the Sun Java site.

grant CodeBase  "http://java.sun.com/" {
     permission java.io.FilePermission "/tmp/*", "read,write";
} 

So where are the standard places that a policy file can exist, and what is the list of permissions?

There is by default a single system-wide policy file, and a single-user policy file. The system policy file is by default located here:

$JAVAHOMElibsecurityjava.policy  (Windows)
$JAVAHOME/lib/security/java.policy  (Solaris) 

The user policy file is by default located in the user’s home directory in a file called this:

.java.policy  (note the leading “.” in the name)) 

The system makes provision for specifying a number of additional policy files, including defining the name of one as a property when you invoke the program, as shown above. This can be done for the appletviewer, too, like so:

appletviewer -J-Djava.security.policy=file:/foo/permit applet.html 

The full list of permissions and subpermissions is shown in Table 25-2. The policytool software will help you navigate these, and you can see why it’s useful.

Table 25-2. Important Permissions and Subpermissions in JDK 1.4

Permission Class Name

Target Name (a subpermission)

Actions

java.io.FilePermission

filenames

read,

write,

delete,

execute

java.security.

AllPermission

java.awt.AWTPermission

accessClipboard,

accessEventQueue,

showWindowWithoutWarningBanner

java.net.NetPermission

requestPasswordAuthentication,

setDefaultAuthenticator

java.net.

SocketPermission

accept,

connect,

listen,

resolve

java.util.

PropertyPermission

read,

write

java.lang.reflect.

ReflectPermission

suppressAccessChecks

java.lang.

RuntimePermission

queuePrintJob, setFactory, setIO,

modifyThread, modifyThreadGroup

getProtectionDomain,

setProtectionDomain

readFileDescriptor,

writeFileDescriptor

loadLibrary.<library name>

accessClassInPackage.<package name>

defineClassInPackage.<package name>

accessDeclaredMembers.<class name>

java.security.

SecurityPermission

getPolicy, setPolicy

getProperty.<property name>

setProperty.<property name>

insertProvider.<provider name>

removeProvider.<provider name>

setSystemScope, setIdentityInfo,

setIdentityPublicKey,

addIdentityCertificate,

removeIdentityCertificate

clearProviderProperties.<provider name>

putProviderProperty.<provider name>

removeProviderProperty.<provider name>

getSignerPrivateKey, setSignerKeyPair

java.io.

SerializablePermission

enableSubclassImplementation,

enableSubstitution

The next section is a step-by-step example of signing a piece of code so that it can write to the local filesystem.

Signing a Java Program

Applets are not allowed to write to the local file system by default. We will walk through the example of how we can sign an applet so that it does have that ability. It’s a lengthy process the first time because you also need to create and register your cryptographic keys.

There are steps that the code signer has to do (here, linden), and steps that the code receiver has to do to run the code (here, sauceboy). You can sign any kind of Java code: applets or applications. Applets always run under the control of a security manager, but you have to provide one if you want an application to have the same level of assurance.

Step 1: Setup for Applet Signing (One-Time)

We’ll start by listing the bits and pieces involved in registering yourself with the Java system as a person or organization that can sign code. Note that you can sign applications as well as applets.

  • Public and private keys: Java uses public key cryptography which involves two keys, one private and one public. Anyone can use your public key, but only you know your private key. There is no practical way to discover one key from the other, but either key can turn a message into seemingly random bits, and the other key can recover it.

  • Encrypting something is like translating it into Martian—the encryption key is an English-to-Martian dictionary, and the decryption key is a Martian-to-English dictionary. Only instead of Martian, we use mathematical ciphers that are a lot harder to search exhaustively.

  • Certificates: Anyone can generate their own keys, and anyone can claim to be whoever they like. To provide better assurance that you are who you say you are, we use X.509 certificates (bit files) in the online world.

  • The keystore database: This repository holds records of all users, their certificates, and the pairs of code keys that each has. There can be several of these files on a system. It replaces the earlier javakey database of JDK 1.1

  • The keytool utility: You’ll be relieved to hear that there is a utility to do all this key generation and database registration. It has lots of different options, but there’s only one command: keytool.

Now that we know the players, let’s go over the rules of the game shown in Table 25-3.

Table 25-3. Getting Your Keys and Register Yourself with a Keystore

Step

Action

Step 1a

Generate your pair of keys.

Step 1b

Generate or buy an X.509 certificate.

Step 1c

Register your keys and certificate in a keystore database.

When you have completed these three steps, you will be able to sign applets.

Although the process may seem cumbersome, remember that these steps have to be done only once and then you can do any amount of code signing. The Java keytool utility does all three steps in one go, so it takes a large number of options to drive it.

Register Yourself and Your Keys in a Java Keystore. As we mentioned, there is only one utility, keytool, to do all the preparatory work, and it has many different options which you can see if you type:

% keytool
keytool usage:

-certreq     [-v] [-alias <alias>] [-sigalg <sigalg>]
             [-file <csr_file>] [-keypass <keypass>]
             [-keystore <keystore>] [-storepass <storepass>]
             [-storetype <storetype>]

-delete      [-v] -alias <alias>
             [-keystore <keystore>] [-storepass <storepass>]
             [-storetype <storetype>]

-export      [-v] [-rfc] [-alias <alias>] [-file <cert_file>]
             [-keystore <keystore>] [-storepass <storepass>]
             [-storetype <storetype>]

-genkey      [-v] [-alias <alias>] [-keyalg <keyalg>]
             [-keysize <keysize>] [-sigalg <sigalg>]
             [-dname <dname>] [-validity <valDays>]
             [-keypass <keypass>] [-keystore <keystore>]
             [-storepass <storepass>] [-storetype <storetype>] 

…and there are many more!

For more information, see the documentation online at java.sun.com/products/jdk/1.2/docs/guide/security/spec/security-specTOC.fm.html.

We use a command of the following form all on one line:

keytool -genkey -storepass password1 -keystore name1
     -alias name2 -keypass password2 

The actual command is like the following, all on one line, remember:

keytool -genkey -storepass soupy99  -keystore lindenstore
          -alias linden  -keypass lime43 

The options mean:

-genkey

Generates a public and private keypair in this operation.

-storepass soupy99

Supplies the password to access this keystore file. It is better not to enter this on the command line, as it can be snooped. If you leave it off, you will be prompted for it.

-keystore lindenstore

This pair of options gives a name to the keystore that you are creating or using. The name can include a pathname.

-alias linden

The option says how you want to refer to the particular entry containing the keys that will be generated. It gives a name to the linden keypair.

-keypass lime43

The option gives a password for accessing and updating the linden keypair. Again, it is better to leave it off and be prompted for it.

When you run the keytool command, you will be prompted to provide more information identifying the person or organization who owns this keypair:

What is your first and last name?
  [Unknown]:  Peter van der Linden
What is the name of your organizational unit?
  [Unknown]:  code grinding shop
What is the name of your organization?
  [Unknown]:  AFU (Cayman Islands) Inc.
What is the name of your City or Locality?
  [Unknown]:  Silicon Valley
What is the name of your State or Province?
  [Unknown]:  California
What is the two-letter country code for this unit?
  [Unknown]:  US
Is <CN=Peter van der Linden, OU=code grinding shop, O=AFU (Cayman Islands)
Inc., L=Silicon Valley, ST=California, C=US> correct?
  [no]:  y 

The keytool takes a few seconds to run, and then this 1.3KB keystore file is generated:

% ls -l
-rw-r--r--   1 linden   staff       1351 Nov 15 14:21 lindenstore 

Now you have a keypair within a keystore and a self-signed X.509 certificate. You are ready to sign code using it.

What Is an X.509 Certificate? To reiterate, anyone can generate their own keys, and anyone can claim to be whoever they like. To provide better assurance that you are who you say you are, we use X.509 certificates (bit files) in the online world.

X.509 is an ISO standard for computer authentication. There are companies in business simply to check your credentials and issue you an unforgeable X.509 certificate in the form of an encrypted file. Search the web looking for “X.509 certificate” for a list of vendors.

You prove who you are to a certification authority using real-world documents then show them your public key, and they issue you a certificate. An X.509 certificate is like a passport, or perhaps better because it’s harder to forge. An X.509 certificate works like a notary public. You identify yourself to the notary public and sign something, and then the notary affixes an official seal to guarantee your signature.

Buying an X.509 certificate from a certification authority is more reliable for your users and will make your code accepted in more places. Generating our own certificate is good enough for this example. The certificate does the same job as a PGP fingerprint. There’s a glossary for these terms online at: java.sun.com/docs/books/tutorial/security1.2/summary/glossary.html.

Step 2: Put All the Files That Make up the Applet into a Jar File

We saw how to put the class files and other resources into a jar file earlier in this chapter. Here is the example code we will use. It is an applet that attempts to write to a local file on the client. Untrusted applets do not have permission to write to local files.

/* <applet
       archive=write.jar    code=write.class
       width=120           height=75>
   </applet>
*/
import java.io.*;
import java.awt.*;
import javax.swing.*;

public class write extends JApplet {

    public void init() {
       try {
           FileWriter fw = new FileWriter("score.txt");
           fw.write("new high score: 14 
");
           fw.close();
       } catch (Exception e) {System.out.println(e);}
  }

    public void paint(Graphics g){
        g.drawString("Try to write a file", 15, 15);
    }
} 

Don’t worry about the I/O details—that will be covered in full in a later chapter. For now, the purpose is to demonstrate that browsers control the resources accessed by applets, and that file I/O is possible from an applet when the permission is granted. Compile the applet and put the class in a jar file.

% javac write.java

% jar -cvf write.jar  write.class 

The applet attempts to open a file and write to it. When you try to run the applet, it will fail with a security error. Untrusted applets are not permitted access to the client file system. After this, we will sign it and try again.

% appletviewer write.java
java.security.AccessControlException: access denied
(java.io.FilePermission score.txt write) 

Step 3: Create a Signed Jar File

To sign a jar file, we use the jarsigner tool (new with JDK 1.2). A typical run might look like this:

jarsigner -keystore lindenstore -signedjar swrite.jar write.jar linden 

The options are self-explanatory. The program takes an unsigned jar file and creates a signed jarfile version of it. (Tip: Use the same name, but prefix an “s” on the beginning.) It signs it with linden’s key from the lindenstore keystore. The utility will prompt you for passwords for both the keystore and the linden keypair.

Enter Passphrase for keystore: soupy99
Enter key password for linden: lime43 

You can see that the following jar files now exist:

-rw-r--r--   1 linden   staff       2249 Nov 15 14:24 swrite.jar
-rw-r--r--   1 linden   staff        977 Nov 15 14:18 write.jar 

Jar files (even unsigned jar files in JDK 1.2) have an extra directory called META-INF that it contains “meta-information”—information about the information in the archive. The MANIFEST.MF file is a list of files to be found in the archive, in the same sense that a manifest is a list of the cargo on a ship.

Step 4: Change the Applet Tag

Now we change the applet tag in our HTML file to refer to the signed version of the jar file. We want users to reference the newly-created signed file instead of the old .jar file.

The new tag will look like this:

<applet

       archive=swrite.jar
       code=write.class
       width=120
       height=75>
   </applet> 

Step 5: The Person Who Runs the Applet Must Import My Certificate

You now have a signed jar file swrite.jar. The runtime system of the code receiver will need to authenticate the signature when the write program in the signed jar file tries to write a file. The authentication is done using a policy file that grants the permission to this signed code.

The person (sauceboy, in this example) who is going to run this applet needs to set up a policy file that says in effect, “I am going to allow file access to code written by user linden.” So sauceboy’s system has to know about linden’s X.509 certificate and public key. Here’s how we tell it.

The signer of the code sends a copy of the certificate authenticating the public key to anyone who plans to run it. That certificate must be put into their own keystore. Here is how linden extracts the X.509 certificate from the keystore using the keytool utility:

keytool -export -keystore lindenstore  -alias linden  -file linden.cert 

Again, the tool will challenge you for the password.

Enter keystore password:  soupy99
Certificate stored in file <linden.cert> 

The file that holds the certificate is a binary file (bear that in mind if you e-mail or FTP it somewhere). Sauceboy must now import that into his keystore by running a command like this:

keytool -import -alias linden -file linden.cert -keystore sauceboystore

Enter keystore password:  sauce99
Owner: CN=Peter van der Linden, OU=code grinding shop, O=AFU (Cayman
Islands) Inc., L
=Silicon Valley, ST=California, C=US
Issuer: CN=Peter van der Linden, OU=code grinding shop, O=AFU (Cayman
Islands) Inc.,
L=Silicon Valley, ST=California, C=US
Serial number: 364f53f0
Valid from: Sun Nov 15 14:21:36 PST 1998 until: Sat Feb 13 14:21:36 PST
1999
Certificate fingerprints:
         MD5:  E8:83:20:2C:99:5E:AD:25:82:F7:28:B4:96:05:F5:8E
         SHA1: CA:EE:D3:1D:D3:A2:00:0E:E7:C8:0E:CC:8D:06:FC:76:E7:2E:6A:3D
Trust this certificate? [no]:  y 

The certificate fingerprints can be used to check that there has been no monkey-business with the certificate. You can read the expected fingerprints on a company letterhead, or off its annual report, or confirm them by phone. Don’t check them by going to the company web site, though.

Step 6: Set up a Security Policy for the User, Allowing Signed Code

The person who wishes to run the signed code (sauceboy, in this example) must now set up a policy file allowing this runtime permission. The policy file is an ASCII file that associates URLs with code signers, with code, and with permis-sions. You can edit the file manually, but there is a GUI utility in JDK 1.2 to help you. The utility is called policytool, so start it up by typing that name. It has the same kind of elementary look and feel as early versions of Netscape. You can’t type directly into text fields; you have to select them from the menu first.

Start policytool and a main window will come up. Using the “Edit” -> “Change KeyStore” menu, type in the new keystore URL for the sauceboy keystore that we created in step 5. Note that the keystore is accessed by an URL, so it can be located anywhere on the Internet (or more likely, your private intranet). Also enter “File” -> “Save as” and enter the pathname for where you want the policy file to go. The screen will look like Figure 25-4.

The Policy Tool utility.

Figure 25-4. The Policy Tool utility.

That takes care of reading the contents of sauceboy’s keystore. Now we need to add a policy entry for the precise permission we want to grant. Press the button marked “Add Policy Entry” to bring up the policy entry screen.

The policy entry screen has two text fields at the top, “CodeBase” and “SignedBy.” If we enter a URL in the codebase field, we are saying that the permission applies to code that arrives from that codebase. Thus, you might enter “ http://java.sun.com ” to apply a permission to all applets that you browse on the Sun Java web site. If you leave the field blank, it means the permission you are about to specify applies to all code, regardless of where it comes from.

The second text field “SignedBy” identifies who signed the code. We need to enter the alias that we used to identify the linden certificate when we entered it into the sauceboy keystore. If you look back a couple of pages, you’ll see we just used the string “linden.”

“Code signed by linden” is shorthand for saying,” Code in a class file contained in a JAR file, where the JAR file was signed using the private key corresponding to the public key that appears in a keystore certificate in an entry aliased by linden.” Phew!

You then click the “add permission” button and select the appropriate permission, what it applies to, and the level of access. The permissions are listed back in Table 25-2. The screen resembles Figure 25-5.

Setting up security.

Figure 25-5. Setting up security.

The “Target” is the file or directory to which you want to apply the permission. The “Action” is the kind of access: read, write, execute, delete. Finish up by clicking “Done” and saving the file.

Take a look at the policy file, and you will see something like this:

/* AUTOMATICALLY GENERATED ON Sun Nov 15 16:31:02 PST 1998*/
/* DO NOT EDIT */

keystore "file:/home/sauceboy/sauceboystore";

grant signedBy "linden" {
  permission java.io.FilePermission "<<ALL FILES>>", "write";
}; 

By the time this book gets into the hands of readers, more browsers are expected to support configurable applet security. One need is to be able to configure browsers to accept or refuse certain X.509 certificates. You’ll want to be able to tell your browser, “Accept applets that are accompanied by certificates from these five companies, and ask me explicitly about any others.”

Step 7: Run the Code Using the Policy File

The final step is to execute the code, like so:

appletviewer -J-Djava.security.policy=file:/etc/sauceboy/permit write.html 

The “-J” option tells the appletviewer to pass the option that follows to the JVM.

The applet will run, and the file will be written successfully to the local filesystem.

Some Light Relief—Software About Nothing

Anyone who has had to do “booth duty” at a computer exhibition knows the problem: Software is nebulous stuff, and very hard to demonstrate. Take a compiler for example. You don’t really have anything to show that is going to make people gasp in astonishment. You type a command-line, the compiler runs and creates an object file, and that’s it. The problem is even worse for utility and system administration software. There’s just plain nothing to see.

A software company based in southern California, Syncronys Softcorp, took this concept to the limit (and then took one step further) with SoftRAM95, a bestselling Windows product. An advertisement on page 81 of the December 1995 issue of Wired read:

double click.

double memory.

Doubling RAM doesn’t have to be hard. Install SoftRAM95 and instantly speed up Windows 95 and Windows 3.0 and higher. Run multimedia and RAM hungry applications. Open more applications simultaneously. Say good-bye to ‘Out-of-Memory’ messages. 4MB becomes at least 8MB. 8MB becomes at least 16MB. Get the idea? (In fact, you can get up to 5 times more memory.) SoftRAM95 works with all 386 and higher desktops and laptops. PC Novice calls SoftRAM the ’real RAM doubler for Windows.’

Executive summary: Don’t Run Windows Without It.”

The trade press named SoftRAM95 as the hottest-selling utility for Windows 95. More than 600,000 people bought SoftRAM95 and Syncronys’s stock price shot up from $.03 a share in March 1995 to $32 a share just five months later. SoftRAM95 works like this in action (see Figure 25-6).

SoftRAM95: Just a pretty face.

Figure 25-6. SoftRAM95: Just a pretty face.

I don’t mean “SoftRAM95 looks like this picture in a book”— I mean “SoftRAM95 works like this picture in a book. It looks pretty but it does nothing.” The program was on the market for several months and sold hundreds of thousands of copies before word started to get out that the emperor had no clothes.

SoftRAM95 was based on an earlier Syncronys Windows 3.1 program that also did nothing. However, it featured a really slick control panel that reported on the amount of memory present and the extra resources that the software said it was providing. The trade press was initially full of favorable reports, but careful consumers noticed that the dials read the same whether or not the Syncronys libraries were on the system, which tended to cast doubt on whether the control panel was reporting what the system was doing, or what it wanted users to think the system was doing.

The jig only started to unravel well after SoftRAM was a big hit in the market. Three independent tests reported that SoftRAM did not work as advertised, and in fact did not work at all. It did not speed up Windows. It did not double memory. The software did not do anything at all. PC Magazine’s technical editor Larry Seltzer reported, “I’ve never seen a product that was so devoid of value as SoftRAM. After careful testing, we found no evidence that SoftRAM95 performs any of the main functions it claims to perform.”

Amazingly, the product continued to sell in boatloads, and with a list price of $79.95, Syncronys was reluctant to admit that the only effect of the software was a placebo effect. Syncronys’s reseller in Germany actually sued German computer magazine, c’t, which was the first to report that SoftRAM didn’t work as advertised. At first, Syncronys circulated a favorable report done by XXCAL labs, claiming that the report “confirmed that SoftRAM95 effectively doubles Random Access Memory (RAM).” After criticism continued to mount, Syncronys issued a press release in October 1995 that admitted, “RAM compression is not being delivered to the operating system.” Syncronys glossed over the critical fact that the software didn’t even attempt any compression of memory, so of course it couldn’t deliver anything at all to the operating system.

At last the Federal Trade Commission began to ask a few half-hearted questions of Syncronys, which announced in December 1995 that it was recalling SoftRAM and would credit or refund purchasers. Even then Syncronys didn’t give up, and wrote to its distributors saying that it would soon be relaunching SoftRAM and creating a version for the Macintosh. And in June 1996 Syncronys had its lawyers warn Dr. Dobbs Journal over an upcoming review of SoftRAM 95. Dr. Dobbs Journal wasn’t intimidated and went ahead and printed the truth in its August 1996 issue without further ado.

Finally, the FTC brought a complaint against Syncronys. It was settled by Syncronys agreeing “not to make representations about the performance, attributes, benefits, or effectiveness of SoftRAM, SoftRAM95, or any substantially similar product unless the representations were true and substantiated.” In other words, Syncronys siphoned millions from unwary customers, and got away clean with a slap on the wrist. In a news story reporting the consent decree, Syncronys CEO Rainer Poertner was quoted as saying that SoftRAM for Windows 3.x “always worked perfectly.” I suppose it depends on your definition of “perfectly.” While the program perfectly delivered a lot of cash into Syncronys’s bank account, it certainly didn’t deliver the memory benefits claimed for it.

Syncronys had perhaps the biggest of the best-selling programs that do nothing, but they are by no means alone in the field. Right now there is a vendor hawking “security” software that supposedly safeguards your system against hostile Java applets. They’re using all the same tools to keep the software on the market: lawyers letters, favorable test reports from “independent” labs, press releases, and so on. And the software has just as much use. Hostile Java applets don’t exist; because of the security measures in place from the first Java release, about the worst that a cracker can do in a Java applet is a “denial of service” attack—chew up CPU cycles that don’t belong to him.

Jerry Seinfeld used to take great pride in his comedy show, saying it was “a show about nothing.” Sometimes life does imitate art. Syncronys had a best-selling Windows product that bore the “Designed for Windows 95” logo that did absolutely nothing.

Addendum: In the summer of 2000, Syncronys’s stock nose-dived to less than one-tenth of a cent. When I last checked their website, it had been taken over by an adult content operator. I was curious to find out who. A reverse DNS look-up showed it was being operated from an address in Yerevan, Armenia. Why am I not surprised?

Further References

Applied Cryptography, 2nd edition by Bruce Schneier. (John Wiley and Sons, New York, NY, 1996), ISBN 0-471-11709-9 (paperback).

A wonderful book. The author has gone to considerable trouble to explain a complicated mathematical topic so that any programmer can follow it. More technical books should be written like it.

There is more information on Java Security at java.sun.com/security, which is Sun’s Java security home page.

The Java documentation has some information which, if you installed the documentation, will be at file:/c:/jdk1.4/docs/guide/security/index.html.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.222.149