Appendix G. Using the jarsigner Tool

This appendix shows you how to use the jarsigner tool of the Java 2 platform to sign JAR files. It can also be used as a command-line reference for the jarsigner tool.

JAR Files

A JAR file is a compressed archive file that is created using the Java archive tool (jar), which is similar to the PKZIP program developed by Phil Katz. It combines multiple files into a single archive file that is compressed using the ZLIB compression library. Although jar is a general-purpose file archive and compression tool, its main purpose is to combine the files used by an applet, application, or API into a single compressed file for efficient loading by a Java-enabled Web browser.

Using JAR files with applets can greatly improve browser performance. Because all the files used by an applet are combined into a single file, a browser needs to establish only a single HTTP connection with a Web server. This reduces the communication-processing overhead on both the browser and the server. File compression reduces the time required to download an applet by 50% or more. This benefits both the applet's user and publisher.

Note

A description of the ZLIB compression format is available at the URL http://www.cdrom.com/pub/infozip/zlib/.

Another feature of JAR files is that they support the capability to sign archived files. This enables browsers to differentiate between untrusted applets and those applets that can be trusted to perform sensitive processing in a secure manner (because they are signed by a reputable identity). The sensitive processing that is permitted to trusted applets is determined by the local Java security policy.

Using the jar Tool

The jar tool is easy to use. You invoke it using the following command line:

jar [options] [manifest] jar-file input-file(s)
						

The jar-file is used as an archive. The .jar extension should be supplied in the command line. The input-file(s) are written as a space-separated list of files to be placed in the archive. Filename wildcard characters may be used (for example, *.class).

The manifest is a file that contains information about the archived files. It need not be supplied—jar will create it automatically and store it as META-INFMANIFEST.INF within the archive. Information about the manifest file can be found in the file docsguidejarmanifest.html that is included with the JDK 1.2 API documentation.

The jar options are used to control the input and output of the jar tool. They are described in Table G.1.

Table G.1. Table G.1 The jar Tool Options

Option Description
c Creates a new (empty) archive file.
t Displays the archive's table of contents.
x [file(s)] Extracts the specified file(s). If no files are specified, all files are extracted.
f Identifies the file to be created, listed, or extracted.
v Generates verbose output.
i [jar-file] Generates index information for the jar-file.
0 Stores files but does not compress them.
M Skips creation of the manifest file.
m manifest Uses the supplied manifest file.
U Indicates that an existing JAR file should be updated.
-C directory Specifies an alternate directory from which classes should be loaded.

If any of the specified files is a directory, the jar tool will process the directory recursively—that is, all class files in that package and subpackage will be included.

Note

The syntax of the jar tool is similar to the UNIX tar command.

Note

The @ character may be used in a jar command, followed by a filename. When this occurs, command arguments are taken from the file (one argument per line) and inserted into the command at the position of the @ character.

Examples of using the jar tool are provided in the following sections.

Creating a JAR File

If you have ever used the UNIX tar command or the DOS PKZIP program, you will find the jar tool familiar and easy to use. In this section, you'll learn how to create a JAR file for the ReadFileApplet applet shown in Listing G.1.

I'll use the ReadFileApplet applet because it uses two .class files, which makes it a good candidate for archival and compression. Go ahead and compile it to produce ReadFileApplet.class and ReadFileApplet$ButtonHandler.class.

Example G.1. The ReadFileApplet Applet

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class ReadFileApplet extends Applet {
 TextArea text = new TextArea();
 Button goButton = new Button("Read Local File");
 Panel panel = new Panel();
 String fileName = "";
 public void init() {
  fileName = getParameter("fileName");
  setLayout(new BorderLayout());
  goButton.addActionListener(new ButtonHandler());
  panel.add(goButton);
  add("North",panel);
  add("Center",text);
 }
 class ButtonHandler implements ActionListener {
  public void actionPerformed(ActionEvent e){
   String s = e.getActionCommand();
   if("Read Local File".equals(s)){
    try {
     FileInputStream inStream = new FileInputStream(fileName);
     int inBytes = inStream.available();
     byte inBuf[] = new byte[inBytes];
     int bytesRead = inStream.read(inBuf,0,inBytes);
     text.setText(new String(inBuf));
    } catch(Exception ex){
      text.setText (ex.toString());
    }
   }
  }
 }
}

Let's use jar to archive and compress the *.class files into a file named rfa.jar:

jar cf rfa.jar ReadFileApplet*.class

You can use the list option of the jar command to see what's inside the rfa.jar file:

jar tf rfa.jar
META-INF/
META-INF/MANIFEST.MF
ReadFileApplet$ButtonHandler.class
ReadFileApplet.class

The only thing that looks out of place is the META-INF/MANIFEST.MF entry. That's the file used to keep a manifest of the JAR file's contents. Go ahead and delete ReadFileApplet.class and ReadFileApplet$ButtonHandler.class. You'll recreate them later in this chapter.

Viewing a JAR File

You're probably wondering how you would include the rfa.jar file in an applet. The answer is that you add the ARCHIVE="rfa.jar" attribute to the applet tag. This attribute tells the browser to load the rfa.jar archive file to find the ReadFileApplet.class file and other related classes. Listing G.2 shows the file ReadFileApplet.htm that is used to display the ReadFileApplet applet.

Example G.2. The ReadFileApplet.htm File

<HTML>
<HEAD>
<TITLE>An Applet that reads local files</TITLE>
</HEAD>
<BODY>
<H1>An Applet that reads local files.</H1>
<APPLET CODE="ReadFileApplet.class" ARCHIVE="rfa.jar" HEIGHT=300 WIDTH=600>
<PARAM NAME="fileName" VALUE="C:AUTOEXEC.BAT">
Text displayed by browsers that are not Java-enabled.
</APPLET>
</BODY>
</HTML>

You can view the ReadFileApplet applet using the appletviewer tool, as follows (see Figure G.1):

appletviewer ReadFileApplet.htm

The applet displays a text box and the Read Local File button. The applet is designed to read the AUTOEXEC.BAT file on Windows systems. However, if you click the Read Local File button, you'll receive an error message, as shown in Figure G.2. That's because the applet is not permitted to read any files. Later in this chapter, you'll use the jarsigner tool to sign the applet and modify your security policy to allow the signed applet to read the AUTOEXEC.BAT file.

Note

NonWindows Users

If you are running Java on a nonWindows system, simply substitute another filename for AUTOEXEC.BAT in Listing G.2.

The ReadFileApplet applet viewed by appletviewer.

Figure G.1. The ReadFileApplet applet viewed by appletviewer.

The unsigned applet is not permitted to read AUTOEXEC.BAT.

Figure G.2. The unsigned applet is not permitted to read AUTOEXEC.BAT.

Extracting the Contents of a JAR File

The x option of the jar tool lets you extract the file's contents. You can use it to re-create the .class files that you deleted:

jar xf rfa.jar

Note that the META-INF directory is also created. This directory contains a single manifest file named MANIFEST.MF.

Delete the .class files and the META-INF directory before going on to the next section.

Signing JAR Files

The next thing that you're going to do is to digitally sign the rfa.jar file. Before you can sign the JAR file, you need to create a public/private key pair and make it available to the jarsigner tool, in the form of a keystore entry. You'll use the keytool (see Appendix F,"Using the Keytool," ) to create a keystore with the public/private key pair.

Note

The keytool and jarsigner tools of JDK 1.2 replace the javakey tool of JDK 1.1.

You can generate a public/private key pair for yourself using the -genkey command of keytool. For example, the following command generates a key pair for the alias "Jamie" in the default keystore:

keytool -genkey -alias "Jamie"

The keytool then prompts you to enter a password for the keystore:

Enter keystore password:  123456

When you enter a password, keytool prompts you for the following additional information:

What is your first and last name?
  [Unknown]:  Jamie Jaworski
What is the name of your organizational unit?
  [Unknown]:  Software Development
What is the name of your organization?
  [Unknown]:  Jaworski & Associates
What is the name of your City or Locality?
  [Unknown]:  San Diego
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=Jamie Jaworski, OU=Software Development, O=Jaworski & Associates, L=San Diego,
Note ST=California, C=US> correct?
  [no]:  yes

Finally, you are prompted to enter a password for your private key:

Enter key password for <Jamie>
        (RETURN if same as keystore password):

I showed you how I filled in this information. You would enter your own information, of course. This information is used to associate an X.500 distinguished name with the alias.

Note

If the -keystore option is not supplied, keytool generates a keystore named .keystore that is stored in the directory specified by the user.home system property.

Using jarsigner to Sign a JAR File

Now that you have created a keystore with your public and private keys, you can use the jarsigner tool and your private key to sign a JAR file. The jarsigner tool is used for both signature generation and signature verification. I'll cover signature generation in this section and signature verification in the next section.

To sign a JAR file, you enter a jarsigner command in the following form:

jarsigner [-keystore keystore] [-storepass storePassword] -keypass keyPassword JARFileName
Using jarsigner to Sign a JAR File alias

The parameters to this command are as follows:

  • keystore—. The name of the keystore to use (for example, MyKeyStore).

  • storePassword—. The keystore password (for example, 123456).

  • keyPassword—. The private key password (for example, 123456).

  • JARFileName—. The name of the JAR file to be signed (for example, rfa.jar).

  • alias—. The alias of the signer (for example, "Jamie").

Additional command parameters are available for the jarsigner command. Use jarsigner -help to obtain a description of these parameters:

jarsigner -help
Usage: jarsigner [options] jar-file alias
       jarsigner -verify [options] jar-file

  [-keystore <url>]             keystore location

  [-storepass <password>]       password for keystore integrity

  [-storetype <type>]           keystore type

  [-keypass <password>]         password for private key (if different)

  [-sigfile <file>]             name of .SF/.DSA file

  [-signedjar <file>]           name of signed JAR file

  [-verify]                     verify a signed JAR file

  [-verbose]                    verbose output when signing/verifying

  [-certs]                      display certificates when verbose and verifying

  [-internalsf]                 include the .SF file inside the signature block

  [-sectionsonly]               don't compute hash of entire manifest

  [-provider]                   name of cryptographic service provider's master class file

I used the following command to sign the rfa.jar file:

jarsigner rfa.jar "Jamie"
Enter Passphrase for keystore: 123456

If the -keystore option is not specified, the default (.keystore) keystore is used. If the keystore password is not supplied, you are prompted to enter this password.

Signing a JAR file causes the JAR file to be updated as follows:

  • A signature (.SF) file is added to the META-INF directory. The name of this signature file is the first eight characters of the alias used to sign the file. This name can be changed using the -sigFile option.

  • A signature block file (.DSA) file is added to the META-INF directory. The name of the signature block file is generated in the same way as the signature file.

The signature file identifies each file in the JAR file, the digest algorithm used in the signing process, and a

digest value. The digest value is the digest computed from the file's entry in the manifest file. Listing G.3 provides an example signature file.

Example G.3. A Sample Signature File

Signature-Version: 1.0
SHA1-Digest-Manifest: LrVFCFftXCITdMRYZKie/E0GWBg=
Created-By: 1.2.2 (Sun Microsystems Inc.)

Name: ReadFileApplet$ButtonHandler.class
SHA1-Digest: TTx0UYjUot7EujvpWi9Ug1UdKUQ=

Name: ReadFileApplet.class
SHA1-Digest: K8SfTC5qVpG0dxTEE5hQy4K1t40=

The signature block file contains the signature of the signature file and a certificate that authenticates the public key corresponding to the private key used in the signature generation. The signature block file is a binary file.

Note

By default, jarsigner uses the SHA-1 digest and DSA signature algorithms to sign and verify JAR files. Other digest and signature algorithms can be installed and used instead of SHA-1 and DSA.

Note

A JAR file can have multiple signers. Each signer signs the JAR file in succession.

Verifying the Signature of a JAR File

The jarsigner tool is also used to verify the signature of a signed JAR file. This is accomplished using the -verify option. The following jarsigner command form is used:

jarsigner -verify JARFileName
						

For example, the following command verifies the signature of edit.jar:

jarsigner -verify edit.jar

If the signature is valid, jarsigner produces the following output:

jar verified.

If the signature is invalid, jarsigner responds with an exception identifying why the failure occurred:

jarsigner: java.util.zip.ZipException: invalid entry size (expected 900 but got
876 bytes)

The jarsigner signature verification process is optimized for performance. This process consists of the following:

  • Verifying that the signature block (.DSA) file contains a valid signature for the signature (.SF) file.

  • Verifying that the signature file entries are valid digests for each of the corresponding manifest (MANIFEST.MF) file entries.

  • Verifying that the digests in the MANIFEST.MF file are valid for each of the files in the JAR file.

Any error encountered in the verification process results in the generation of a security exception.

Changing the Applet Security Policy

The signing of JAR files provides the basis for developing an applet security policy. JAR files that are received from trusted sources whose signatures can be verified may be given greater privileges than JAR files that are unsigned or come from an untrusted source. In this section, I'll show how to update the default applet security policy (based on digital signatures) to permit ReadFileApplet to read your AUTOEXEC.BAT file.

The default security policy is defined in the java.policy file located in the java.homelibsecurity directory, where java.home refers to the value of the java.home system property. To grant permission for the ReadFileApplet applet in rfa.jar to access AUTOEXEC.BAT, I added the following lines at the beginning of java.policy:

keystore "file:/C:/Windows/.keystore";

grant {
  permission java.io.FilePermission "/AUTOEXEC.BAT", "read", signedBy "Jamie";
};

The first line specifies that my default keystore (located at C:Windows.keystore) should be used. The grant statement specifies that permission to read C:AUTOEXEC.BAT should be granted to code that is signed by Jamie.

Now use appletviewer to run ReadFileApplet with the new policy:

appletviewer ReadFileApplet.htm

Click the Read Local File button. The appletviewer displays your AUTOEXEC.BAT file, as shown in Figure G.3.

The ReadFileApplet is trusted to read your AUTOEXEC.BAT file.

Figure G.3. The ReadFileApplet is trusted to read your AUTOEXEC.BAT file.

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

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