Signed Applets are a technique of adding a
digital signature to an Applet to prove that it came
untampered from a particular trusted author. Signed Applets
can be given more privileges that ordinary Applets.
They even allow someone finding a jar file floating about the Internet to know
that file is what it purports to be, even without checking with the author’s
website.
Signed Applets are potentially dangerous.
They have power to potentially damage your machine, e.g erase all your files or
format your hard disk, or post your diary on LiveJournal. Just because an Applet
is signed does not make it safe. Anyone, even a terrorist, can write a signed Applet.
There are many schemes for signing and OKing signed Applets
to run on your machine. I will concentrate on the most recent scheme.
Sun Plugin 1.3+ RSA Plug-in Style Applet Signing
This is the standard signing scheme, for JDK 1.3 and up.
This signing schemes uses a policy file where the system administrator pre
clears certain dangerous Applets to run without
asking the user. It is supported by Opera, Netscape, Firefox, Mozilla and IE.
Permission can also be a simple go/no go user grant, or individual permissions
to do a variety of dangerous deeds.
Unless you are forced to support other styles of signing at gunpoint, I suggest
you ignore every signing scheme but his one. Demand your clients upgrade to
recent browsers that support the latest Sun JVM. Here
is the basic recipe for making your Applet work with
Sun-style signing:
- Buy a Sun Java Code Signing certificate from Thawte.
You use keytool to create your certificate request.
You then send the public key part of your certificate to Thawte for them to
digitally sign as authentic and return to you. You don’t disclose your
private key to Thawte.
- Alternatively, after reading my warnings,
you can create a free phony certificate using keytool.
- Write your Applet as normal Java code. You don’t
need to include any special permission-asking code. Just go ahead and do naughty
things like read the local hard disk or talk to servers other than mother.
Normally, your Applet just goes ahead and does what
it wants, without any sort of pre-check. If it gets a SecurityException,
it catches the exception and does its best to carry on. A signed Applet
that was not granted permission can still do useful work, recovering from SecurityException
exception after SecurityException the way Wassup
does. However, if you want to avoid SecurityExceptions
in the middle of your application code, you can do probes like this to see what
will cause trouble.
- Then build your Applet as normal in a jar using jar.exe.
- Then sign your jar using jarsigner.
- If you want others to be able to use your Applet
without hassle they must import your phony cert into their browsers as an
officially accepted cert. This is not strictly necessary, but if you don’t
do this, Sun will disparage your Applet and
discourage users from granting it permission. For real certs you can skip this
step so long at the browser has the root cert for the signing authority
installed.
- You might consider adjusting the policy file at
client sites to either give your Applet permission
to run without having to OK it each time, or to control precisely what is it
allowed to do, in terms of where on disk it can write, and just what naughty
things it is allowed to do. You, as programmer, don’t control your client’s
policy files. Typically some site administrator bureaucrat does and he puts the
same policy files on nearly every desk in the institution.
java.policy
The simplest way to grant extra permission to run is to have the user click grant,
for an all or nothing permission. However, there are finer grained methods using
the java.policy file. For more information see the Sun
documentation on policy-based security.
Sun’s JDK Technote Guide on
Security : available:
For a first cut, you can safely ignore all the
information on Security Managers. You, as application programmer, don’t
ever directly call their methods. They get called as a side effect of attempting
potentially dangerous activity. For Sun style security you need a special Sun
style *.cer X.509 certificate. A common policy file for all apps on a machine is
stored in
J:\Program Files\java\jdk1.6.0_11\jre\lib\security\java.policy
You can edit java.policy as a text file, or use policytool
to edit it. The rules about running all possible apps anywhere on the web have
to be encapsulated all in this one place. You can append more grants on the end
to handle additional apps, but this change must be made to every workstation
potentially to use the new app. Happily you can grant blanket powers to all apps
signed by a given certificate, so you don’t need to keep changing the
policy file, at least for in-house apps.
It is actually a little more complicated than that. There are three files to be
concerned with:
J:\Program Files\java\jdk1.6.0_11\jre\lib\security\java.security
points to the policy files, usually two, one called:
J:\Program Files\java\jdk1.6.0_11\jre\lib\security\java.policy
and the other called user.home/.java.policy. To
find out what user.home is, check out the
system properties with Wassup.
It will be something like C:\Documents and Settings\%username%.
And if that was not confusing enough, the JDK has two JREs, the public one in C:\Program Files\java\jre6
and the debugging one in J:\Program Files\java\jdk1.6.0_11\jre
each with its own set of policy files.
.keystore
The signing certificates are stored in a common file user.home/.keystore
managed using keytool. There is one for each user
of the machine. On your clients, this would possibly contain your phony self-signed
certificates (the public key portion). There would be no need to install your
purchased signing certificates. You only need to install your signing
certificates (with private key) on your development machine where you sign your
jar files. Of course, your phony certificates(public key only) would also be
installed in the .keystore files of your development
machines too.
cacerts
The root certificate authority certificates are stored in:
\sdk1.4.2_02\jre\lib\security\cacerts
They are no longer by default stored in the browsers. You can add to the cacerts
file with keytool using the password changeit.
There is only one cacerts shared by all users. However,
like the java.policy files, there is one cacerts
per JRE.
One common error to make is to change the wrong copy of cacerts,
.keystore or java.policy. If
you don’t know what you are doing, change them all!
Enhancements in JDK 1.3+
Read about the
over the 1.2 plug-in. trustProxyServer is now by
default true, which means websites are no longer required to confirm their DNS
name. The rules on matching of the jar signer with a root authority certificate
have been relaxed. You can now preload Applets jars
into lib/plugin.
When Do You Need to Sign?
Check out the list of restrictions on unsigned
Applets. If you don’t need to do any of those things, you don’t
need to sign. In general you have to sign if your Applet
does anything potentially dangerous like reading or writing the disk, or
pestering various servers on the net other than the one it was loaded from.
Overall Process of Creating A Signed Applet
There are many different Applet-signing schemes, but
the general flow is as follows:
- Buy a certificate or "forge" one. Do
this well in advance. It is quite a song and dance to get one. You may need a DUNS
number, a listed business phone number, a passport, a document from a notary…
- If you use a phony certificate, you will probably
want in some way install it on all client’s machines. Techniques vary. See
how I do it. If you use a real one, that step should not be necessary.
- Write your Java code. This may require method calls to request fine grain
permission. Coarse grain security does not require these. Make sure you never
execute these calls unless you are running under the appropriate browser. The
necessary classes won’t be present otherwise and further they don’t
like being called outside the browser.
- Create a jar, picking the files you need from all over. I use ant
and genjar.
- Sign the jar with jarsigner. I use ant
and the signjar task. Oddly signjar
uses jarsigner.exe.
- In some corporations, the administrator will install a fine-grain policy file on
all the client machines, (such as C:\WinNT\Profiles\username\policy.java).
You have to talk him into modifying that file to give you the permissions you
need.
- When you run the Applet, grant the requested
privileges.
Avoiding Signed Applets
If you don’t plan to distribute Applets to
others, or if you want to postpone the agony for a while, you can avoid the
hassles of signing to allow your Applets to do
naughty things, by using JDK 1.6.0
and creating a java.policy file in your J:\Program Files\java\jdk1.6.0_11\jre\lib\security
and C:\Program Files\java\jre6\lib\security
directories. In those files add these commands:
grant codeBase "http://yourservername/*" {
permission java.security.AllPermission;
};
grant codeBase "file:///C:/yourjavafilesdir/-" {
permission java.security.AllPermission;
};
This gives blanket permission to all locally created Applets
to do what they please.
Other ways to avoid signing are converting your Applets
to applications by adding a main method. See Applet
for how. This can be useful for debugging. Get the Applet
working as an application first, then worry about Appletness
and signing later. Also consider Java Web Start
as an alternative to Applets.
Signed Applet Tutorials and Documentation
Happily, there is a wealth of online documentation to read:
Tame vs Wild Applets
A tame Applet is intended
to be run by a captive audience, usually within a single corporation. Typically
a network administration will do special preparation of all client machines such
as installing a certificate or policy file before the Applet
can be run. Sometimes the certificate is installed into the browser, sometimes
into a separate file. The author typically works for the corporation. The Applet
might be signed, self-signed or unsigned. If there are any security decisions to
me made to allow the Applet to run, the permissions
are granted by the network security administrator ahead of time.
In contrast, a wild Applet
is intended to be run by the general public without any special preparation such
as installing a certificate or policy file. A wild Applet
in one you might just stumble across in your web browsing. You don’t know
much about the author. The Applet might be signed,
self-signed or unsigned. If there are any security decisions to me made, the
browser asks the end user for permission each time the Applet
is run, using technobabble.
Some security schemes are aimed at writing tame and others at writing wild Applets.
User grant schemes are primarily for wild Applets,
where the java.policy schemes are primarily for tame Applets.
Tame schemes typically use an ASCII policy text file that describes all
the Applets, users and websites and what permissions
each has. It is thus just about impossible for an individual Applet
to automatically maintain. It is designed to be maintained by a network
administrator who tightly controls just what can be run. The policy files can
also control the activities of applications. Most people find it easier to
compose the policy file with a text editor than using Sun’s GUI policytool.
Tame schemes typically use a certificate file completely separate from the
browser’s list of root certificates. This is managed by keytool.
Again certificates from all different Applets are
merged in this file. This makes it almost impossible for an Applet
to manage its certificates. The network administrator must compose and control
this file.
Signed Applet Tips
Using signed Applets, and especially native code in
signed Applets, is a little trickier than you might
first think, largely because Applets were designed
for security, not programmer convenience:
- If the end user refuses to grant permission, your Applet
will run anyway! It has to soldier on somehow without permission. It can either:
- Die on a java.security.AccessControlException
leaving people to think your Applet has a bug.
- Catch the java.security.AccessControlException
and give some explanation for poor performance to the user.
- Check if the user has granted permission, and if
not, chastise the user for lack of trust, and possibly carry on in some degraded
mode.
- Use a proxy server so that your Applet will talk
only to one host, even if two hosts actually service its requests. Then you don’t
need a signed Applet.
- The policy file is just an ASCII text file. It is quite a bit easier to
manipulate it with a text editor than the policytool
GUI.
- You need to order your digital certificates well in advance. You need to know
which kinds to order. You will need a corporate DUNS number to apply.
- There are many different Applet security/signing
schemes, including two for Netscape, two for Internet Explorer, two for Sun’s
JDK 1.1 Plugin, two for Sun’s JDK 1.2 Plugin, five for Sun’s JDK 1.3+
Plugin/Web Start and one for the Macintosh. Each kind uses a different type of
signing certificate, though there are some multi-purpose certificates you can
buy. You have the possibility of self-signed dummy certificates or real ones
from Thawte or Verisign. On top of that you have the choice of coarse or fine-grain
capabilities. Make sure you are ordering the right kind of code signing
certificate. You want a Java 1.5 code signing certificate.
- The Applet must download and install the needed DLLs
and certificates on the client machine in magic directories. This is extremely
difficult to do, but a piece of cake with JWS.
- You need to write JNI glue to your native C++/C/ASM code.
- Sun’s JNI tutorials presume Solaris and have no hints on how to handle NT
and Windows issues.
- Signed Applets take much longer to load because of
the CPU-intensive verifying of the signatures of each class. Don’t sign
jars just for the heck of it.
- You are best to tackle JNI in applications and signed Applets
without JNI separately before combining them. For details on how, see JNI.
- You can use the Wassup Amanuensis
to find out what your browser thinks the user.home
directory is and what it is using for a java.class.path
and any other system properties.
- For the Netscape and Internet Explorer RSA certificate-based schemes, or with a
Thawte DSA Java Plug-In certificate, you don’t need to install the
certificate on the client machine, just sign the jar file with your expensive
certificate. The signing authority root certificate that Opera, Netscape,
Firefox, Mozilla or Microsoft pre-install in the browser is sufficient to check
authenticity of your signed jar. See certificate
for more details.
- You can create your own free self-signed phony certificates, but then somehow
you must pre-install them on the client’s machine. The main time the
hassle of self-signed certificates would be practical is if you had control of
all the client machines, and were not allowing the general public to use your Applets.
- For you to be able to verify jars without installing your signing certificate on
all the client machines, there needs to be a chain of trusted authorities and
automatic verification of public keys with those authorities. Signed Applets
are not magic cloak to protect you from bugs. Any boob can create a phony
certificate using the signing tools and sign the Applet
with it. (You do this when you are debugging and waiting for your real
certificate to arrive.) Further, even a trusted author can write buggy code. See
my essay on the general theory of digital
certificates based on Steven C. Den Beste’s work.
- Java’s impregnable Applet security is a bit
like France’s impregnable Maginot line prior to the second world war.
Hitler simply went around it. Windows security is Swiss cheese, so it is easy to
attack Java from the rear by replacing the various executables with doctored
versions.
Java Web Start
Just when you thought you were beginning to understand all this, Sun invented
yet another type of sandbox called Java Web Start.
JWS apps are usually signed, but they work more like ordinary applications.
Obsolete Signing Schemes
There are over a dozen different, incompatible Applet
signing/security schemes.
| Scheme |
Applet Type |
Signing Tool |
Certificate Type |
Jar Type |
Request Privilege |
Notes |
| Netscape |
tame |
Netscape
signtool 1.3 |
self-signed RSA X.509 |
jar |
netscape.security.PrivilegeManager.
enablePrivilege ("UniversalThreadAccess") |
Netscape only. You must manually install the phony certificate in the client’s
Netscape browser. Fine grained control with capabilities. For debugging, you don’t
need any certificate real or phony; you can turning on codebase principles
support. Note: Netscape and Sun RSA signing tools are not interchangeable. |
| Netscape |
wild, tame |
Netscape
signtool 1.3 |
Verisign or Thawte RSA X.509 |
jar |
netscape.security.PrivilegeManager.enablePrivilege ("UniversalThreadAccess") |
Netscape only. There is no need to install the certificate on the client
machine, so long as the browser comes pre-installed with the Verisign or Thawte
RSA root certificate. Fine grained control with capabilities. Note: Netscape and
Sun RSA signing tools are not interchangeable. |
| Microsoft Internet Explorer 5.5 |
tame |
signcode |
self-signed Authenticode RSA X.509 |
cab |
com.ms.security.PolicyEngine.assertPermission (PermissionID.NETIO) |
Internet Explorer only. You must manually install the phony certificate in
the client’s IE browser. It puts them in the registry under the entry HLM\Software\Microsoft\System
Certificates. Fine grained control with PermissionIDs. |
| Microsoft Internet Explorer 5.5 |
wild, tame |
signcode |
Verisign or Thawte Authenticode RSA X.509 |
cab |
com.ms.security.PolicyEngine.assertPermission (PermissionID.NETIO) |
Internet Explorer only. There is no need to install the certificate on the
client machine, so long as the browser comes pre-installed with the Verisign or
Thawte Authenticode root certificate. Fine grained control with PermissionIDs. |
| Java Plug-in 1.1 |
tame |
Javakey |
self-signed DSA |
jar |
Use Javakey to install the certificates in the identitydb.obj
on the client machine. You would need a signed Applet
to automate the install — catch 22. |
simple go-no-go. No granularity. In practice, users must manually install
your certificate (as well as the Java Plug-in) before their browsers will
recognize your signed Applet. |
| Java Plug-in 1.1 |
tame |
Javakey, jarsigner |
Thawte Java 2 DSA X.509 cert delivered in a PKCS#7 wrapper. |
jar |
There is no need to install the certificate on the client’s machine,
so long as the browser comes pre-installed with the Thawte root DSA certificate.
Use coarse grain permission only. |
| Java Plug-in 1.2 |
tame |
Javakey, jarsigner |
self-signed DSA |
jar |
Use keytool to
install the public part of the certificate on the client’s machine in the
user-home directory as a .keystore file. Use coarse
grain permissions, or optionally use policytool
to create a policy file that lists the fine grained
permissions required. Install that on the client’s machine in the user-home
directory. |
| Java Plug-in 1.2 |
tame |
Javakey, jarsigner |
Thawte Java 2 DSA X.509 cert delivered in a PKCS#7 wrapper. |
jar |
There is no need to install the certificate on the client’s machine,
so long as the browser comes pre-installed with the Thawte root DSA certificate.
Use coarse grain permission or optionally Use policytool
to create a policy file that lists the fine grained
permissions required. Install that on the client’s machine in the user-home
directory. |
| Java Plug-in 1.4+, Netscape 8.0+, Opera 7.5+ |
tame |
Javakey, jarsigner |
self-signed RSA |
jar |
Use keytool to
install the public part of the certificate on the client’s machine in the
user-home directory as a .keystore file. Use coarse
grain permissions, or optionally use policytool
to create a policy file that lists the fine grained
permissions required. Install that on the client’s machine in the user-home
directory. |
| Java Plug-in 1.4+, Netscape 8.0+, Opera 7.5+ |
tame |
Javakey, jarsigner |
Thawte Java 2 RSA X.509 cert delivered in a PKCS#7 wrapper. |
jar |
There is no need to install the certificate on the client’s machine,
so long as the browser comes pre-installed with the Thawte root DSA certificate.
Use coarse grain permission or optionally Use policytool
to create a policy file that lists the fine grained
permissions required. Install that on the client’s machine in the user-home
directory. |
| Java Plug-in 1.4+, Netscape 8.0, Opera 7.54 |
tame |
Netscape signtool 1.3 |
Verisign or Thawte RSA X.509 |
jar |
There is no need to install the certificate on the client’s machine,
so long as the browser comes pre-installed with the Thawte root RSA certificate.
There are problems with having the precise Verisign root certificates installed
in Internet Explorer. See Verisign for details. Only coarse grain permission is
available. The class files must contain no Netscape capabilities calls. |
This allows Netscape jars, but not Netscape capabilities. Works in IE as
well. Does not work in Opera with Verisign certificates since the root signing
certificate is not provided, though the Thawte ones are. Note: Netscape and Sun
RSA signing tools are not interchangeable. |
| Java Plug-in 1.4+, Netscape 8.0, Opera 7.54 |
? |
? |
? |
? |
Some sort of FIPS 140-1 process that does not use certificates. |
| Apple Macintosh MRJ |
tame |
Javakey |
Verisign or Thawte RSA x.509 or DSA or self-signed |
jar |
You must always manually install the certificate in the browser. |
Requires complex sign.directive text-form certificate that is not-integrated
with the browser’s list of certificates. JDK 1.1.8 compliant. Not
supported in any browser yet, but supported in Netscape 5.0 and IE 5.0. You can
test in the Mac AppletViewer. Supplanted by RSA in JDK 1.3+. |
Netscape 4.79 (Obsolete)
Netscape 4.79 has a proprietary code signing scheme its own special kind of
certificate, called Netscape Object signing. You will need Netscape’s
signtool. For details of signing see the signtool
entry in the Java glossary.
In your Java code you also need to request permission for the various classes of
sandbox security violations (sometimes called system targets, Netscape
capabilities or privileges) that you require like this:
import netscape.security .PrivilegeManager;
...
try
{
PrivilegeManager.enablePrivilege( "UniversalConnect" );
}
catch ( netscape .security.ForbiddenTargetException e )
{
}
The permission only lasts until the method that requested permission exits. It
persists automatically in methods you call. Happily when you ask a second time
for permission, the security manager will not pester the user with a dialog box.
Make sure your compile-time classpath includes the Netscape security classes in:
\Program Files\netscape\communicator\program\java\classes\java40.jar.
Netscape will automatically provide these classes at run time. Don’t put
them in your jar.
You must also add a special line to your APPLET invocation HTML:
archive="myapp.jar"
Asks the end user running the Applet. Often he is
too naive to know if he should grant permission or not. Netscape
Security Capabilities
Microsoft Authenticode (Obsolete)
Microsoft’s code signing uses its own special kind of certificate and own
special tools. You will need Microsoft’s Java
SDK. The SDK includes cabarc, dubuild, extract, makecert, cert2spc and signcode
to create a signed *.cab file instead of a *.jar. Unlike Netscape permissions,
you don’t always need to put any code in your Applet
to request permission. Instead you sign your app with low, medium or high
security. Low means the fences must be low to let it do whatever it wants. It
does not mean low privilege. You must also add a special line to your APPLET
invocation HTML:
<param name="cabbase" value="myapp.cab">
There are circumstances when you do need to put permission asking code in your Applet.
See this discussion.
IE drives me nuts just to install, so I have done all I could to avoid playing
with its brain damaged Java and signing scheme. Sorry I can’t be more help
here.
Netscape Style RSA Signed Applets: Java Plug-In
1.3+ (Obsolete)
Simply signing with a Netscape 4.79 style certificate, using the Netscape 4.79
Signtool 1.3, without any PrivilegeManager code gives you an all or nothing
grant when you run that code in the 1.3+ plugin. In Netscape 8.0 all PrivilegeManager
code is ignored. The same technique works also for Opera. For more information
see the Sun documentation on Applet:
This is probably the simplest approach to deal with
wild Applets — ones the general public will
run.
Internet Explorer 5.5 Authenticode style (Obsolete)
Ask the end user running the Applet. Uses cab files
instead of jars.
Plugin 1.2+ DSA Plug-in Style (Obsolete)
Use a policy file where the system administrator pre clears certain dangerous Applets
to run without asking the user. Often the system administrator is too busy to
make the necessary changes to the policy files to allow users to get their work
done.
Signed Applet Tips For Obsolete Signing
Schemes
- If the user of the signed Applet is behind a
firewall, for some strange reason, if he invokes the Applet
using the IP rather than the DNS name of the website in the codebase e.g CODEBASE="http://65.110.21.43/"
instead of CODEBASE="mindprod.com", all
works. Otherwise you get a trustProxy Property error
message. This problem may have been fixed.
- The fiends who devised these security schemes should be shot. The designs
deliberately make it very difficult to write a single piece of code that will
work under all security schemes. You pretty well have to maintain three separate
versions of your code, one for Netscape, one for Internet Explorer and one for
the various versions of the Java Plug-in. Thankfully the older schemes have all
but disappeared. It is even hard to find documentation on them any more. Good
riddance!
- Netscape wants a jar file and IE a cab for its proprietary scheme. Mostly today
IE uses the Java 1.3+ scheme.
- With the Netscape scheme, permission is granted only until the immediate caller
of the permission-granting method exits. You can’t introduce even one
layer of indirection, or your permissions immediately expire.
- Each scheme uses different exceptions, which have to nest neatly with try blocks.
You must be careful never to execute any code from another security scheme,
because its classes won’t be available. Happily, with Java, you can have
calls to such methods in your code, so long as you never actually execute them.
- You can create dummy classes and dummy methods so that you can safely call
methods from all security schemes. Netscape no longer supports their old scheme.
- Beware the catch-22 of not being permitted to examine interesting system
properties until you have decided on which security scheme you need to use. You
need permission before you can examine the restricted system properties.
- To your Netscape prefs.js file add this entry:
user_pref("signed.applets.codebase_principal_support",
true);
- Make sure you have the latest JDK. Early versions did not use the cacerts
file.
Learning More
Applet signing is considerably simpler than it used to be now that the obsolete
schemes have died away and you don’t have so much conflicting information
to digest.
Sun’s JDK Technote Guide on
Policy File Permissions : available:
Sun’s JDK Technote Guide on
Privileged Blocks : available:
Sun’s JDK Technote Guide on
Security Tools : available:
Sun’s JDK Tool Guide to
Jarsigner : available: