mypackage” for the package name, and “
MyApplet” for the applet name.
Here's the Java source code for the sample applet:
jarutility automatically creates and adds a default manifest file to your JAR, but it won't include the entries needed for a signed applet (or signed WebStart application). So the next step is to create a text file with the correct entries.
To add (or override) manifest entries, put your entries in a text file
and use an option with
jar to have it include those entries.
Here's how to add the correct manifest entries for our demo applet:
Create a UTF-8 text file (let's call it
MyAppletManifest.txt”) with these three lines in it:
Permissions: all-permissions Codebase: * Application-Name: My Applet
Make sure each line ends with a NEWLINE (the “Enter” key). A common error is to forget to hit Enter after that last line.
Previously (Java 7U45 and older), the default was to run
unsigned applets in the sandbox, and signed applets with all permissions.
But Oracle made a change for the next version, Java 7U51,
Permissions manifest entry is now required for all
applets and WebStart apps (Oracle calls these Rich Internet
Applications, or “RIAs”).
If your applet doesn't require extra permissions, change
all-permissions” to “
Codebase” entry lists the places from
where this applet can be loaded.
The entry shown says the applet can be loaded from anywhere,
but you shouldn't use that for a real applet.
Instead, you should list your testing computer(s), usually
localhost, and the real website(s) to which
you plan on deploying your applet.
Here's a sample entry for an applet I plan on testing locally (on my
computer), and then deploying on a webserver at
Codebase: localhost *.localdomain 127.0.0.1 *.example.com 192.0.2.2
You need to list both the hostname and its IP address
since one doesn't imply the other for some reason.
(For IPv6, you would need to add
::1 for localhost
However, IPv6 addresses are not supported
in the JAR file manifest specification as of Java 8U31.)
Additional entries can be included to enhance security further;
those won't be discussed here (but see the manifest resources at
the bottom of this web page).
MyApplet.jar”. Use the
jarutility to create a new JAR (Java ARchive) file, and include the manifest entries from the file you created:
jar -cvfm MyApplet.jar MyAppletManifest.txt mypackage
(Additional files, such as media files, could also be included in the JAR; simply add file or folder names to the end of the command line.)
applettag of your HTML file, add the “
archive” attribute. The value of the archive attribute is the URL of the JAR file. If the JAR file is in the same folder as the HTML file, just use the file name as the URL:
<APPLET CODE="mypackage.MyApplet" ARCHIVE="MyApplet.jar" HEIGHT="120" WIDTH="400">
This should result in a non-signed applet. If the Java 7 control-panel security settings are set to “medium”, you should be able to run this applet locally. But not if you use the default security settings (or have a more recent version of Java that eliminated the medium setting). For that, you must sign the applet, or add it's codebase (location) to the Java Exception List (discussed below).
Since this applet is unsigned. it runs in a sandbox regardless of the manifest entries we used. You will see an “Access Control Exception” (ACE) when it attempts a restricted operation:
java.security.AccessControlException: access denied ("java.util.PropertyPermission" "user.dir" "read")
Here is a sample HTML file showing the correct applet tag:
<HTML><HEAD> <TITLE>My Applet - Demo signed applet</TITLE></HEAD> <BODY> <APPLET CODE="mypackage.MyApplet" WIDTH="400" HEIGHT="120" ARCHIVE="MyApplet.jar"> </APPLET> </BODY></HTML>
Here's what this looks like when run (a PNG image if Java
is disabled in your browser):
This is easier to do than to describe. There's only two commands to run, and the first one only needs to be run once. (The second command is run whenever you need to sign a new or updated JAR file.) Here's what you need to know, and how to do it:
A digital signature is constructed from a private key, plus the code (.class files) and other data to be signed. What's great about that is any changes to the code/data or the digital signature will result in an invalid signature. A valid signature provides assurance that the code you got was unaltered since it was signed. The additional data includes the identity of the signer, so that can't be changed either.
To verify a digital signature, your system needs the signed code and data, and a public key that works with the private key used to sign the code. You generate these keys in pairs, and keep one private, backed-up, and secure. The other is the public key, which you can freely share. The two keys have a special mathematical relationship, so that you can encrypt or sign data with one key, but it takes the other to decrypt or verify. The public key is included in the JAR file with your code, so the recipient can easily verify the signature.
These keys are huge, and are generated using random numbers. Even knowing the method used and the public key, nobody can figure out the corresponding private key. But if an attacker wanted to forge a digital signature, they would need to determine the private key used. The keys are so large that guessing numbers to find the private key is futile. So this digital signature is unforgeable, provided nobody gets a copy of your private key. To prevent this, private keys are kept in password-protected files.
When you sign your JAR file, both the signature and the public key are added to the JAR file. But not just the public key; that wouldn't prove much. (An attacker could generate their own key pair, sign their modified code with their private key, and include their public key in the JAR; if you checked, the digital signature would appear valid.) The public key is part of a certificate; it is the certificate that is added to the JAR. A certificate includes: your public key, the algorithm used to sign the JAR, the signer's ID, and other information.
To prevent false claims of identity (“This Applet was signed by Bill Gates”), the certificate itself must be signed by a well-known, trusted third party called a certificate authority (or “CA”). Your computer has a list of the public keys of CAs, updated regularly. (Note that the Java JRE, your operating system, web browsers, and other software all contain separate lists.) So your system first verifies the digital signature on the certificate, showing the true identity of the code signer. Then it verifies the digital signature on the code from the public key in the certificate. Thus, your system not only knows the code wasn't modified since it was signed, but also it has assurance that it knows the true identity of the signer.
CAs charge money for this service. As of 12/2014, code signing certificates that work for any code, not just Java JARs, are available from Comodo resellers for about $80/year. Both cheaper and (much) more expensive certificates from various CAs are available, but not all of them are included in the current JRE's trusted CA list.
Instead, you can become your own CA, and then sign your own certificate. Such certificates are called self-signed. While you should never trust self-signed code from the Internet, you can use them yourself for testing your code and for educational purposes. When ready to deploy your code to the world, use a real CA-provided code signing certificate to sign code.
With that background, here's the two steps to sign a JAR file:
keytool -genkeypair -alias mykey
This will create a private key to sign your code with, and a public
key that can be used to validate the digital signature.
Since Java 6, it will also generate a self-signed certificate.
The keys will be put in the default file in the default location (the file
.keystore” within your “HOME”
A file containing a set of keys is called a keystore.
You can specify an option to use a different keystore if you want.
alias you give is the name for the pair of keys.
(Sometimes, you may have multiple key pairs, and might use different keys
for different applications.
So you need to give each pair a name, or alias.)
There are defaults for everything (including the
which does default to “
mykey”), but you can
use additional command line options to override the defaults.
One default to consider changing is the validity period of 90 days. After that, the certificate is expired and won't (or shouldn't) work to sign any code; you would have to generate a new certificate (or pay to renew an existing one). If you're generating keys for use in a one semester Java course (four months), or a longer course, you will probably want to change this default. Here's the option to add for a one year certificate:
keytool -genkeypair -alias mykey -validity 364
(For code signing certificates obtained from CAs, the validity period depends on how much you pay. It generally ranges from one to five years.)
keytool utility is interactive.
It will ask you for your name, your organization's name,
your department (“organizational unit”), and the city, state,
and country of your organization.
You can include all that on the command line, but this way is often
You will also be prompted for a password to protect the private
key, and another for the keystore file.
You should pick good, different passwords; access to your private keys
have legal implications!
You can write these down, but please don't put the passwords
on a note taped to your monitor, or store them in an unsecured or
Keep the passwords safe.
Note, you can also put the passwords as options on the
command line (if you include everything,
prompt you for any additional data), but generally, that isn't a good idea.
You can view the contents of your keystore with:
Or, if you want the gory details:
keytool -v -list
If you are happy with your key pair, be sure to back it up someplace, away from your computer. A small USB flash disk can be used to back up your keystore, and that disk can be put in a secure location. Saving your keystore on a CD-ROM would be a better idea.
To sign your JAR file with a real, non-self-signed certificate,
keytool to export your certificate data in a form ready
to be signed by some CA.
This file is called a “certificate signing request”, or
Use the command (assuming your key pair is named mykey):
keytool -certreq -alias mykey -file mykey.csr
You generally email
mykey.csr or upload it to the
CAs website, submit proofs of identity, and pay them.
(Some CAs have web forms to fill out, and they create the
CSR and key pair for you.
Generating your own CSR has the advantage of keeping your
private key private and off of the Internet.)
Sometime later, they send back the signed certificate. You can then import that into your keystore file with:
keytool -importcert -alias mykey -file cert_file
(You must specify the alias with this command even if using the default alias name, or the certificate won't import correctly!) After that, use the imported certificate the same way as you would the self-signed certificate we use in this demo.
Self-signed JAR files will display a warning message about an UNKNOWN publisher. You must use a CA-signed certificate to have your name appear. When the publisher is UNKNOWN, some security settings may prevent the applet from running at all.
(See using a real certificate for more information.)
jarsigner -signedjar MySignedApplet.jar MyApplet.jar mykey
This will ask you for the password(s) needed to access your private key.
(If you don't include the option
jarsigner will overwrite the original JAR file listed!)
The process is fast.
As of Java 7U51, this will issue a warning that you didn't use a time stamp when you signed your code. Time stamps are useful when certificates are revoked by a CA or have expired, so Java can check if the code was signed before or after revocation/expiration. Without a trusted, valid time stamp, the system needs to assume it was signed after, and is therefore invalid. You need to list the URL of a trusted Time Stamp Authority, or “TSA”, when signing a JAR. Just as with Certificate Authorities, these generally charge money for the service (most CAs operate a TSA for their customers' use, free of charge). This service is usually cheap, and some TSAs do offer some limited, but free, time-stamping services.
To have your signature time stamped, include an option to identify a TSA; there are several ways to identify one. For example:
jarsigner -signedjar MySignedApplet.jar -tsa URL MyApplet.jar mykey
The European Union maintains (as of 2014) a list of approved and trusted TSAs, at https://ec.europa.eu/.../eu-trusted-lists-certification-service-providers. A Google search for “public time stamp authority free” will turn up some, such as these (as of 2015):
For example, to use the Aloaha TSA, the command would be (one long line):
jarsigner -signedjar MySignedApplet.jar -tsa http://card.aloaha.com:8081/tsa.aspx MyApplet.jar mykey
(This is not an endorsement of this TSA.)
When done, you should check the result:
jarsigner -verify -certs -verbose MySignedApplet.jar
Finally, you need to update the
applet tag in the
HTML file to refer to the new (signed) JAR file:
<APPLET CODE="mypackage.MyApplet" ARCHIVE="MySignedApplet.jar" HEIGHT="120" WIDTH="400">
That should be it.
The result is (shows as a PNG image if Java is disabled
in your browser):
And here is the result when using a valid code-signing certificate
(the result is (a PNG image if Java is disabled in your
Notice the difference security dialog that shows, and how you can make it
remember your decision to allow this applet:
To make this signed (with a real certificate) applet, I used a different manifest file:
Permissions: all-permissions Codebase: localhost *.localdomain 127.0.0.1 ::1 *.wpollock.com *.hccfl.edu Application-Name: My Applet
In the future, you can use the same key and certificate to sign other
JAR files (or newer versions of this one).
You'll only need to re-run the one
Starting with Java 7U51, the user can add exceptions to the rule that prevents unsigned or self-signed apps from running, by white-listing URLs using the Java control panel. The exception list is a list of sites from which you will allow unsigned or self-signed code to run. Note that unsigned applets, even if their codebases are added to the exception list, will run in the security sandbox. So if your applet or WebStart app require extra permissions, you must sign them. You should add a couple of entries to enable running code from your local computer:
http://localhost/ http://127.0.0.1/ https://localhost/ https://127.0.0.1/ file:///
file:/// entry is needed unless you're
running a local server such as a web server, Tomcat, Glassfish, etc., and plan
on serving up Java applets and/or WebStart applications.
In that case, you may need to specify a non-standard port number.
For example, by default the Glassfish server uses port 8080, so you need
to add “
IPv6 isn't supported by this exception list as of Java 8.
Also the JRE doesn't resolve DNS names to
IP addresses, so you should have both the host name as well as the
IP addresses listed.
Note you will get a warning with
Since you are using localhost for those protocols, it doesn't matter
(no security implication) so you should ignore those warnings.
The browser plug-in API, NPAPI, was pioneered by Netscape long ago and is no longer considered secure. This is why most browsers today no longer support such plugins, used for Flash and for Java. Soon, Applets will be a dead technology; we'll all have to learn to use Java WebStart I suppose. (All Java applications, including WebStart and others, support code signing as described here.)
There are still some web browsers that support plugins using NPAPI, and thus support Java Applets. One such browser is Pale Moon, a Mozilla browser fork that keeps the original Firefox appearance (menus, status bar, etc.).
As usual, you must have the same type of browser as your JRE, 32-bit or 64-bit. When most browsers supported Flash and Java, I used 32-bit versions (since there is no 64-bit Flash). Now that most browsers don't, I've noticed many of the ones that do support NPAPI come in either 32-bit or 64-bit versions. So my advice today would be to install a 64-bit JDK and JRE, and use the 64-bit version of Pale Moon. (You can install two different JREs if you want to support both.)
To test, move the signed JAR file and the HTML file to another
Otherwise, the original package may be found on
and your signed JAR would be ignored.
appletviewer to test!
In older versions of JDK,
defaulted to “all-permissions”, whether or not the applet
Now it defaults to “sandbox”, and there is no way to
override that, even with signed applets!
is a non-Oracle alternative that uses the older “all-permissions”
The best plan may be to test signed apps using a web browser.
pscode.org/appleteer/ (from archive.org)
How to sign and timestame a Java Jar file — K Software (A Comodo partner)
Java code signing how-to — www.GoDaddy.com
How to remove private password from PKCS12 certificate — ServerFault.com