March 9, 2021
Hot Topics:

Signing Code with JDK 1.2

  • By Developer.com Staff
  • Send Email »
  • More Articles »

Creating a simple policy for signed applets

JDK 1.2 introduces the notion of policy. Creating, understanding, and managing security policy for signed mobile code is a difficult and complex problem. Since this discussion is about signing code and not about constructing policy, an extremely simple example of how to construct policy is presented. Creating good policy is beyond the scope of this article. The example policy is strong enough to allow an applet limited file access to the host machine.

Java policy files can be created with a new tool that comes with JDK 1.2 called policytool. This application has a GUI to guide users though the many twists and turns encountered when creating policy files. It's a very simplistic GUI with no on-line help. In it's current form as of beta4, it is only useful if one does not know the syntax of a policy file.

Policy files are plain-text files that follow a format outlined at Default Policy Implementation and Policy File Syntax.

Permissions that can be granted in a java policy file are outlined at Permissions in JDK1.2.

To grant an applet permission to write or create any file in the c:\tmp directory, assuming the applet comes from http://www.friendly.com/~mybuddy/applets/ and is signed by a certificate known in the default keystore by the alias friend, create a file called .java.policy in the directory known to the VM as user.home which contains:

  keystore ".keystore";
  grant signedBy "friend", 
    codeBase "http://www.friendly.com/~mybuddy/applets/" {
      permission java.io.FilePermission "c:\\tmp\\*", "write";

Note the double backslashes. All Win32 pathnames must use double backslashes to indicate directories. UNIX pathnames use regular singleton forward slashes. codeBase entries follows URL syntax.

Sign only privileged code

Applets that request permission to leave the sandbox are usually built for doing serious business tasks. These applets that require access to the local system are most likely some of the larger applets in terms of code size. It is unlikely that these applets will be built completely by one developer or one software company. Chances are some of the components of an applet will be bits of utility code found on the Internet or purchased from a tool vendor. A smart organization wants to sign only code that it produced. Third party utility code cannot be safely vouched for.

If all the code is signed, then any code can leave the sandbox based on the policy. But if some code in an applet is from a third-party, it should not be signed unless the individual signing the code is willing to vouch that the third-party code won't try to do anything malicious or introduce a security hole that others can exploit. To say the least, we don't recommend signing code you don't completely understand.

JDK 1.2 presents an API for privileged blocks. Privileged blocks are meant to be small sections of code that have a higher privilege than the code that invoked them. JDK 1.2beta4 changed the API for privileged blocks from previous beta releases. Using this API, the only code that needs to be signed is the code that invokes the AccessController class, and the code that performs the privileged action. All other code can remain unsigned, preventing it from leaving the sandbox on its own. Documentation on the new API can be found at New API for Privileged Blocks.

There are two things to consider when writing signed code that will be integrated with unsigned code. First, make the code in the privileged block as small as possible. The less code that is privileged, the less chance that granting it higher privilege will result in nasty and unwanted side-effects. Second, to prevent mix-and-match attacks, all the code for the applet should live in one JAR file, even if the third-party libraries that are used by the applet live in their own JAR.

To sign some portions of a JAR file and leave others unsigned takes a number of steps we'll cover now. First create a JAR file containing all classes that need to be signed. Classes that need to be signed when using privileged blocks include all classes that contain the call to the

method, and the class that is passes as the argument to

jar cvf MyApp.jar Signme1.class Signme2.class

List all the classes that need to be signed in this step. Once the JAR containing classes that need to be signed is created, sign the JAR with jarsigner:

jarsigner MyApp.jar mykey

Now, add the remainder of the classes in the application to

. The JDK 1.2 version of jar added the v flag, which allows JAR files to be updated with new files.

jar uvf MyApp.jar Other1.class Others.class

All the remaining classes in the application should be added to the JAR in this step. If parts of the application are already in a JAR or ZIP file, they will need to be un-archived before being JARed into the new partially signed JAR file. To verify that all went correctly, use jarsigner to verify the contents:

jarsigner -verify -verbose MyApp.jar

Only the classes that were added before jarsigner was invoked to create the signature will be marked as signed. All the other classes will be listed, but no certificate or signature will be associated with their listing. If jarsigner fails to verify the entire JAR, or classes that are supposed to be signed appear not to be, use the jar command to list the contents of the JAR.

jar tvf MyApp.jar

The first entry in the JAR must be META-INF/MANIFEST.MF. If the manifest file is missing or not in the first position in the file, the JAR will not verify properly. Following the MANIFEST.MF file should be a .SF and .DSA file. If either of those files is missing, then the signature is missing from the JAR. Remove the JAR file and start over. If the commands listed above still move the META-INF/MANIFEST.MF file out of the first position in the file, it may not be possible to create a JAR containing signed and unsigned code. The JAR command with JDK 1.2beta4 did not move the META-INF/MANIFEST.MF file around in the JARs we created using the process described above.

Comparison to Netscape Object Signing

Last week, we discussed Netscape Object Signing. Here's a brief summary of major differences from the JDK 1.2 keytool/jarsigner system.

  • Netscape requires getting a certificate from a Certificate Authority. Keytool generates self-signed certificates.
  • Netscape uses its own security classes for granting and managing privileges. JDK 1.2 uses only classes in the core API for its security work.
  • Netscape manages certificates for the user. JKD1.2 requires the user to locate and install certificates by hand using keytool.
  • Netscape prompts the user for approval when an applet tries to request privileges. JDK 1.2 consults the policy file when privileges are request, without informing the user.
  • The level of granularity of control differs. When Netscape grants a "UniversalFileRead" privilege, the applet can read anything on the client. JDK 1.2 can restrict file reads to only certain directories on the client.

Summing up

It's difficult to say if Sun's approach will enter widespread use. It may require one of the major browser vendors to adopt and support the use of keytool and jarsigner. Downloading and installing the Java Plug-In, finding, downloading and installing certificates, and managing policy are three hoops that Netscape users don't have to jump through. For developers, there's a trade off. Developing for Netscape requires paying for a certificate from a CA and tying their code to Netscape libraries. JDK 1.2 developers have to convert all their HTML pages with the HTMLConverter.

To see an example of an applet signed using jarsigner for JDK 1.2, take a look at To View the Signed Applet. Of course, to view the applet, you'll need the Java Plug-in.

Next week, we'll discuss Authenticode, Microsoft's Java code signing scheme.


Tom O'Connor is a software engineer in the research division at Reliable Software Technologies. His interests are computer security and object-oriented software development.

John Viega is a research associate at Reliable Software Technologies, in Sterling, Va. He holds an M.S. in Computer Science from the University of Virginia. He developed and maintains Mailman, the Gnu mailing list manager. His research interests include software assurance, programming languages, and object-oriented systems.

Portions of this article will appear as an appendix in the forthcoming book Securing Java: Getting Down to Business with Mobile Code (John Wiley & Sons, 1998), the second edition of McGraw and Felten's book, Java Security: Hostile Applets, Holes, & Antidotes.

Page 2 of 2

This article was originally published on October 15, 1998

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date