Signing Code with JDK 1.2
Last week we examined Netscape's Object Signing model for granting applets higher privileges. This week, we'll examine the code signing system in Sun's JDK 1.2, which is a complete replacement for the system in JDK 1.1.
Getting started with keytoolThe first step in working with JDK 1.2 is getting the latest beta version from Sun. Members of the Java Developers Connection (JDC) can download Early Access releases of JDK 1.2 software. Membership in the JDC is free with registration. Once registered, point your browser to Java Development Kit 1.2.
The name of the default keystore file is ".keystore", and is located in the directory named by the "user.home" Java System Property. The value of "user.home" on Solaris is "$HOME/"; on Win32 it is either the value of USERPROFILE, or the combination of HOMEDRIVE and HOMEPATH, or the directory in which JDK 1.2beta4 is installed. It is possible to have multiple keystores. Changing the keystore that the current keytool command will operate on is done through the -keystore <path to keystore> option.
Generating a public and private key pair and self-signed certificate can be performed from the command line in one shot without the need to create any directives files. All keys and certificates stored in the keystore are accessible through an alias. An alias is a name associated with a certificate entry that keytool uses to uniquely identify each certificate under its control. To generate a certificate keyed by the alias keyname, run the command:
keytool -alias keyname -genkey
keytool will begin prompting for information. The first prompt is for a keystore password. This password will be needed for all further keytool and jarsigner operations on this keystore. It must be at least six characters long and is unfortunately echoed to the screen as it is typed. This means that the keystore password can be leaked to casual observers whenever keytool or jarsigner is used.
Once the password has been entered, keytool prompts for some personal information, such as name, company name, city, state, and country. All this information is stored in the generated self-signed certificate which is saved in the default keystore location. All the personal information is displayed for verification before keytool generates the keys and certificate. After the certificate and keys are generated, keytool prompts for another password. Each certificate has its own password, separate from the keystore password. Entering nothing does not give the key an empty password. It gives the certificate the same password as the keystore. jarsigner will not prompt for the passwords of certificates that have the same password as the keystore, so it may appear that a certificate has no password. However, if the password of the keystore changes, the passwords of the certificates do not change, so jarsigner will start prompting for not only the password of the keystore, but for the certificate as well. The command to change the password of a keystore is:
keytool will prompt for the old password, and the new password twice, all in cleartext. This command does not affect the passwords of certificates in the keystore, including those that happen to have the same password as the keystore.
A small weakness of the keytool certificate generation system is that a user can accept all the default values for the personal information prompted for before certificate generation. The default value for all the questions is "Unknown". So keytool will generate a valid certificate which can be used to sign JAR files, but is filled with bogus information. No data validation is performed by keytool, so it is possible to, say, create a certificate for Thomas Jefferson. However, there are a set of options to keytool that allow certificates to be exported in a format suitable for submission to a Certificate Authority. The Certificate Authority authenticates that the keytool certificate is for who it says its for and returns a certificate that can be imported into keytool with another set of command line options. We were unable to find a Certificate Authority to do this for us, so we can't say if it works or not. What we can say is that if a CA hasn't vouched for a keytool generated certificate, the JDK still accepts it as being valid.
Certificates generated by the system will be valid for just under one year by default. To change the length of validity for a certificate to n days, add the flag
To view the fingerprints of certificates in the keystore, use the command:
To view the personal information about the issuer and owner of the certificate, run:
keytool -list -v
Signing a JAROnce a private key has been generated, jarsigner can be used to mark a JAR file with the public key of the signer. The command to sign a JAR file called
jarsigner SignMe.jar keyname
jarsigner will prompt for the keystore password, and the private key password if different than the keystore password before signing the JAR file. To monitor the progress of the signing process, run:
jarsigner -verbose SignMe.jar keyname
jarsigner can also be used to verify that a JAR has or has not been signed and by whom. For a simple signed/not signed answer for a JAR file
jarsigner -verify Unknown.jar
To get more information from the verification process, such as the signing status of each file in the JAR file, the personal information from the certificates used to sign each file in the JAR, and whether or not the certificate is known in the default keystore, run:
jarsigner -verify -verbose -certs Unknown.jar
After each signed file in the listing will be the personal information encoded in the certificate for the entity that signed the file. If that certificate is known in the keystore, the alias it is known by will appear in parenthesis after the certificate's personal information.
Turning over the keysUntil the certificate used to sign the JAR is made public, no one can grant any permissions to the enclosed applet. To export a copy of the keyname certificate from the keystore into a file
keytool -export -alias keyname -file mycert
As usual, keytool will prompt for the appropriate passwords. When the command finishes, the file
There is currently limited support for a JAR signed with the JDK tools. Sun provides support through the Java Plug-In. The Java Plug-In is meant to be a replacement VM for browser's default VMs. (For an article on the Java Plug-In itself, check out The Java Plug-in: using the newest versions of Java with your old browser.)
Plug-In version 1.1.1 does not necessarily support JDK 1.2. Though the Java Plug-In can be configured to use different VMs installed on the local system, the Plug-In hangs the browser when pointed to a 1.2 VM on Solaris. Documentation for the Win32 version of the Plug-In mentions running a program off the Start Menu to configure the Plug-In. The installation script does not create a program group for a Plug-In Control Panel as advertised under Windows NT unless the user performing the installation has permission to create program groups. The latest version of the Plug-In for Win32 ships with JDK 1.2beta4. An Early Access version of Plug-In version 1.2 for Solaris is available to members of the Java Developer's Connection at Java Plug-in 1.2 Early Access 1.
Any HTML pages that contain 1.2-signed JAR files must be converted using the HTMLConverter application. Converting the HTML ensures that the applet will run in the Plug-In and not in the browser's default VM. HTMLConverter changes the <APPLET> tag on an HTML page into the <EMBED> and <OBJECT> tags for Communicator and Internet Explorer respectively. Download the HTMLConverter application from Java HTML Converter Download Page.
Running a signed appletThe first step upon encountering a signed applet is to locate the certificate of the entity that signed the JAR file and import it into the local keystore. Assuming that the certificate can be located and placed into a file called
keytool -import -alias analias -file acert
An entry in the keystore is created keyed by the name
Page 1 of 2