Java's support of applets was one of the early factors that led to Java's immense popularity. However, Java applets have achieved less success over the last few years than was expected. There are a number of technical reasons for the failure of applets to live up to their early expectations:
Fortunately, Sun worked hard over the years to address these shortcomings. There are now a number of reasons why applets are becoming a better solution for mobile code.
The above factors, combined with increased high-performance microprocessors and Internet connections, make applets a more appealing alternative to delivering executable content. In this column, I'll focus on the latest release of the Java plug-in (version 1.3) and its support for RSA signed applets and dynamic trust management.
The Java plug-in provides a way for users to run Sun's latest JVM and API within their browsers. The plug-in is run in place of the browser's native JVM and API classes.
For Java developers, the advantages of the plug-in are tremendous. The plug-in enables developers to write their applets for the latest version of Java. It is assured that their applets will work consistently and reliably with both older and newer browsers, whether they are from Microsoft or Netscape or whether they run on Windows, Linux, Solaris, or several other versions of Unix.
How does it work?
The Java plug-in works in generally
the same way as other browser plug-ins, such as Flash and
QuickTime. An HTML converter (available
from Sun) converts <applet> tags to the
<object> and <embed> tags used
to identify plug-in content to Internet Explorer and Navigator.
The plug-in appears to Internet Explorer as an ActiveX
control. When Internet Explorer encounters the
<object> tag of a converted HTML page (that
references the Java plug-in), it will check to see if the plug-in is
installed. If the plug-in is installed, Internet Explorer will load
and run the plug-in and use it to execute the applet referenced by the
<object> tag. If the plug-in is not installed,
Internet Explorer will download it from Sun and then install it (after
asking the user for permission to do so).
When used with Navigator, the plug-in takes advantage of
Navigator's plug-in API to simplify download and installation. The
first time that Navigator encounters an applet's
<embed> tag, it displays a missing plug-in icon to
the user. If the user clicks on the icon, Navigator walks the user
through the process of downloading and installing the plug-in. After
the plug-in is installed, it will execute any applets referenced by
<embed> tags.
The plug-in does not replace the browser's native JVM. The
browser's native JVM is still used to run applets that are referenced
by <applet> tags. The plug-in is run in place of
the browser's native JVM when the browser encounters
<applet> tags that have been converted to
<object> or <embed> tags by
Sun's HTML converter. No conversion of the applet's Java code takes
place. The HTML converter only converts <applet>
tags to <object> and <embed>
tags within the HTML files that reference applets.
The plug-in and HTML converter are freely available from Sun.
Evolution of the Java Plug-In
The Java plug-in is not
a new development. Plug-ins have existed for JDK versions 1.1 and
1.2. What's new and interesting about the Java plug-in 1.3 is its
support for RSA signed applets and dynamic trust management.
Previous versions of Java plug-in supported DSA signed applets. The Digital Signature Algorithm (DSA) was developed by the U.S. National Institute of Standards and Technology (NIST) (see http://www.nist.gov). Even though DSA has been adopted as the standard for digital signatures within the U.S., the RSA algorithm is by far the most popular algorithm for digital signatures.
The RSA signature algorithm is a derivative of the RSA public-key encryption algorithm. RSA code signing certificates are supported in a uniform manner by both Navigator and Internet Explorer; DSA certificates are not. Prior to Java plug-in 1.3, a developer needed to obtain (and pay for) two code signing certificates -- one that was compatible with Navigator and one that was compatible with Internet Explorer. With Java plug-in 1.3, a single RSA code-signing certificate works with both Navigator and Internet Explorer.
Versions of Java plug-in prior to 1.3 required that the user's plug-in be statically configured to map sets of permissions to potential signers. This approach was cumbersome and difficult to manage. Java plug-in 1.3 provides support for dynamic trust management, which uses the browser's native certificate API and certification authority database to verify the certificates of code signers and to assign permissions to the signers. This is accomplished in a dynamic manner when signed JAR files are processed by the plug-in. Dynamic trust management eliminates the need to statically assign permissions to code signers.
To show how the security features of Java plug-in 1.3 work and to illustrate their benefits, we'll develop a simple port scanner and then deploy it as a signed applet.
A port scanner is a program that checks to see if a TCP port is open. Internet servers, such as Web servers and mail servers, listen on TCP ports for connections from clients, such as Web browsers and mail programs. Web servers typically listen on port 80 and Simple Mail Transport Protocol (SMTP) servers usually listen on port 25. You can use a port scanner to tell whether a particular Internet host supports a TCP service on a particular port.
Security Implications of Port Scanners
Our port scanner will attempt to make a TCP connection to a specified
host and port to determine whether the host is listening on that
port. The default applet security policy prevents an applet from
making TCP connections to hosts other than the one from which it is
loaded. This means that our applet will need to be trusted to make
connections to arbitrary hosts. This is accomplished by giving it an
appropriate permission. In order to enable the applet to be eligible
for this permission, we'll sign it using an RSA code signing
certificate.
See It In Operation
Before we get into the details of the applet's implementation, you may
want to see work. That way you'll have an idea of what to expect. The
applet can be run from
http://www.toolery.com/tools/portscanner/scan.jsp. You'll need
version 4 or later of Internet Explorer or version 3 or later of
Navigator to run the applet.
When you open up the applet's page, your browser will check to see if the Java plug-in version 1.3 is installed. If not, it will prompt you to install it. The Internet Explorer installation is a little smoother than the Navigator installation. Internet Explorer will pop-up a simple installation wizard, while Navigator waits until you click the plug-in icon before it initiates the installation process.
Once you've installed the plug-in, it will download and attempt to
run the SimpleScannerApplet from a JAR file named
scan.jar. When your browser encounters the JAR file's
signature, it will prompt you to determine whether or not you want to
trust the signed code. The plug-in will provide you with a prompt to
accept the signed applet. You can choose to accept it for the current
browser session, always, or never. If you don't accept the
certificate, the applet won't be able to perform sensitive operations,
like scanning other hosts. You can also click More Info to get more
information about the signer.
When you click the More Info button the following dialog is shown.
You can use the dialog to examine the contents of the signer's code signing certificate.
Assuming that you've accepted the certificate, the following applet will be displayed.
Enter a host name and port number and click the Scan button to see if the specified port is open on the host. For example, if you scan OnJava.com on port 80, you'll get the following output because ONJava's Web server listens on port 80.
However, if you scan OnJava.com on port 23, you'll get the following output. That's because port 23 (which is used for the telnet protocol) is closed on OnJava.com.
Note that the scanner reports the host's IP address in parentheses. Some hosts may have more than one IP address. These hosts can have some Internet services run on one IP address and other services run on the other addresses. If you want to scan a host using a specific IP address, enter the host's address in the Host name or IP address field. If a host does not have a name, you can just refer to it by one of its IP addresses.
|
The SimpleScannerApplet Source Code
Now that you know
what the scanner does, let's see how it works. Listing 1 shows the
source code of the SimpleScannerApplet. It extends the
Swing JApplet class and defines two inner classes:
Scanner and ScannerException. The
Scanner class handles the clicking of the Scan button and
performs the actual scanning. The ScannerException class
is used to throw scanner-related exceptions.
Listing 1. The SimpleScanner Applet
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.net.*;
public class SimpleScannerApplet extends JApplet {
// Declare the GUI components used by the applet
JTextField hostTextField = new JTextField("localhost",20);
JTextField portTextField = new JTextField("80",5);
JTextField resultsTextField = new JTextField(40);
JButton scanButton = new JButton("Scan");
JLabel hostLabel = new JLabel("Host name or IP address: ");
JLabel portLabel = new JLabel("Port number: ");
JLabel resultsLabel = new JLabel("Results: ");
JPanel mainPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
public SimpleScannerApplet() {
// Layout the applet's components
Border etched = BorderFactory.createEtchedBorder();
// Add an etched border to the main panel
mainPanel.setBorder(BorderFactory.createTitledBorder(etched, "Simple Port Scanner"));
// Host and port fields in top panel
topPanel.add(hostLabel);
topPanel.add(hostTextField);
topPanel.add(portLabel);
topPanel.add(portTextField);
// Scan button and result field in bottom panel
bottomPanel.add(scanButton);
bottomPanel.add(resultsLabel);
bottomPanel.add(resultsTextField);
// Add top and bottom panels to main panel
mainPanel.add(topPanel);
mainPanel.add(bottomPanel);
// Set up the button's event handler
scanButton.addActionListener(new Scanner());
// Add the main panel to the applet's content pane
getContentPane().add(mainPanel);
}
// The Scan button's event handler does the actual scanning
private class Scanner implements ActionListener {
// Declare fields used as scan parameters
String host;
InetAddress address;
int port;
String ip;
// Handle the button's action event
public void actionPerformed(ActionEvent ev) {
out("Checking scan parameters ...");
if(validParameters()) {
out("Scanning ...");
try {
// Try to connect to the host/port
Socket s = new Socket(address, port);
// No exception: SUCCESS
out("Port "+port+" is open on "+host+" ("+ip+").");
s.close();
}catch(Exception ex) {
// Could not connect
if(ex instanceof SecurityException) out(ex.getMessage());
else out("Port "+port+" is closed on "+host+" ("+ip+").");
}
}
}
// Validate scan parameters
private boolean validParameters() {
try {
host = hostTextField.getText();
String portString = portTextField.getText();
// Convert host name to an InetAddress object
address = InetAddress.getByName(host);
// Get the host's IP address
ip = address.getHostAddress();
// Convert the portString to an int
port = Integer.decode(portString).intValue();
// Make sure that it's in range
if(port > 65535) throw new ScannerException("Invalid port.");
}catch(Exception e) {
// Handle any validation-related exceptions
out(e.getMessage());
return false;
}
return true;
}
// Convenience method for writing results
private void out(String msg) {
resultsTextField.setText(msg);
}
}
// Used to identify invalid scan parameters
private class ScannerException extends Exception {
public ScannerException(String msg) {
super(msg);
}
}
}
SimpleScannerApplet
The
SimpleScannerApplet begins by declaring the GUI
components that it displays. It uses Swing components for maximum
compatibility across browser platforms.
// Declare the GUI components used by the applet
JTextField hostTextField = new JTextField("localhost",20);
JTextField portTextField = new JTextField("80",5);
JTextField resultsTextField = new JTextField(40);
JButton scanButton = new JButton("Scan");
JLabel hostLabel = new JLabel("Host name or IP address: ");
JLabel portLabel = new JLabel("Port number: ");
JLabel resultsLabel = new JLabel("Results: ");
JPanel mainPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
The SimpleScannerApplet constructor lays out the
applet's GUI and creates an instance of Scanner to act as
the Scan button's event handler.
public SimpleScannerApplet() {
// Layout the applet's components
Border etched = BorderFactory.createEtchedBorder();
// Add an etched border to the main panel
mainPanel.setBorder(BorderFactory.createTitledBorder(etched,
"Simple Port Scanner"));
// Host and port fields in top panel
topPanel.add(hostLabel);
topPanel.add(hostTextField);
topPanel.add(portLabel);
topPanel.add(portTextField);
// Scan button and result field in bottom panel
bottomPanel.add(scanButton);
bottomPanel.add(resultsLabel);
bottomPanel.add(resultsTextField);
// Add top and bottom panels to main panel
mainPanel.add(topPanel);
mainPanel.add(bottomPanel);
// Set up the button's event handler
scanButton.addActionListener(new Scanner());
// Add the main panel to the applet's content pane
getContentPane().add(mainPanel);
}
Scanner
The Scanner inner class performs
the actual scanning. It begins by declaring field variables that store
the scan parameters.
// Declare fields used as scan parameters
String host;
InetAddress address;
int port;
String ip;
It then implements the actionPerformed() method of
java.awt.event.ActionListener to handle the clicking of
the Scan button. It uses the validParameters() method to
determine whether the user supplied a valid host name/IP address and
port number and to convert the users inputs into an
InetAddress object and int port value.
A try-catch statement is used to catch any exceptions
that result from the scanning. An attempt is made to create a TCP
socket to the specified address and port. If the attempt is
successful, then the port is identified as being open and then the
socket is closed. If the attempt is unsuccessful, then an exception is
thrown by the Socket constructor. The catch
block handles this exception by checking to see if the exception is a
SecurityException or some other type of exception.
If a SecurityException is thrown, then the message
associated with the exception is displayed in the Results
field. Otherwise, the port is identified as being closed for the
specified host/IP address.
// Handle the button's action event
public void actionPerformed(ActionEvent ev) {
out("Checking scan parameters ...");
if(validParameters()) {
out("Scanning ...");
try {
// Try to connect to the host/port
Socket s = new Socket(address, port);
// No exception: SUCCESS
out("Port "+port+" is open on "+host+" ("+ip+").");
s.close();
}catch(Exception ex) {
// Could not connect
if(ex instanceof SecurityException)
out(ex.getMessage());
else
out("Port "+port+" is closed on "
+host+" ("+ip+").");
}
}
}
The Scanner class defines two other methods that support the
scanning process. The validParameters() method checks to
see if the user has entered a valid host/IP address and port number
and then converts those values from String objects to an
InetAddress object and int port value.
// Validate scan parameters
private boolean validParameters() {
try {
host = hostTextField.getText();
String portString = portTextField.getText();
// Convert host name to an InetAddress object
address = InetAddress.getByName(host);
// Get the host's IP address
ip = address.getHostAddress();
// Convert the portString to an int
port = Integer.decode(portString).intValue();
// Make sure that it's in range
if(port > 65535)
throw new ScannerException("Invalid port.");
}catch(Exception e) {
// Handle any validation-related exceptions
out(e.getMessage());
return false;
}
return true;
}
The out() method simplifies the display of output to
the Results field.
// Convenience method for writing results
private void out(String msg) {
resultsTextField.setText(msg);
}
ScannerException
The ScannerException class extends
java.lang.Exception to provide a mechanism for
identifying scanner-related exceptions.
// Used to identify invalid scan parameters
private class ScannerException extends Exception {
public ScannerException(String msg) {
super(msg);
}
}
|
Why SimpleScannerApplet needs to be trusted
The SimpleScannerApplet needs to be trusted because it
has the potential to make network connections to arbitrary Internet
hosts. This capability is not permitted by the default applet security
policy. Attempts to make connections to hosts other than the one from
which the applet is loaded will result in the throwing of a
SecurityException.
The following HTML file can be used to run the applet.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"DTD/xhtml1-transitional.dtd">
<html>
<head><title>SimpleScannerApplet</title></head>
<body>
<div style="text-align: center">
<h1>SimpleScannerApplet</h1>
<applet name="ScanApplet" code="SimpleScannerApplet.class" archive="scan.jar"
width="600" height="125">
Java not supported.
</applet>
</div>
</body>
</html>
If you compile the apple and run it iwth appletviewer and the HTML above, you'll get the following output.
You'll be able to scan your local host for open TCP ports because the appletviewer loads the applet from your local file system.
However, if you try to scan other hosts, you'll encounter a security exception.
Using SimpleScannerApplet with Java Plug-in 1.3
In order to be able to use SimpleScannerApplet to scan
other hosts, we'll make it available as an RSA signed applet that
executes via the Java plug-in 1.3. This involves the following
steps.
I'll walk you through each of the above.
Using the jar Tool
JAR files are used to archive the
class files and other files used by applets and applications. JAR
files are similar to Unix tar files and Windows zip files. The
applet's classes must be packaged into a JAR file for code
signing. Sun's keytool only signs JAR files and not individual class
files.
The process of creating a JAR file is simple. Go to the directory
where you compiled SimpleScannerApplet.java. You'll find
the following .class files in this directory:
SimpleScannerApplet$Scanner.class
SimpleScannerApplet$ScannerException.class
SimpleScannerApplet.class
SimpleScannerApplet$1.class
Use the following command to create a JAR file named
scan.jar that packages these files:
jar -cvf scan.jar *.class
The above command will generate the following output:
added manifest
adding: SimpleScannerApplet$1.class(in = 180) (out= 130)(deflated 27%)
adding: SimpleScannerApplet$Scanner.class(in = 2376) (out= 1249)(deflated 47%)
adding: SimpleScannerApplet$ScannerException.class(in = 453) (out= 276)(deflated 39%)
adding: SimpleScannerApplet.class(in = 2185) (out= 1096)(deflated 49%)
If you've used the Unix tar command, you'll notice the similarity between the jar syntax and the tar syntax.
Obtaining an RSA Code Signing Certificate
To sign
scan.jar, you'll need an RSA code signing certificate. This step is
the most complicated one in the process and can take days to weeks
depending upon the certificate authority that you use.
The first thing that you'll need to do is to create an RSA public-private key pair, a self-signed certificate, and a keystore to hold the key pair and the certificate. Fortunately, you can use Sun's keytool to accomplish this in a few simple steps.
Open up a command line window and enter the following command. (You
can substitute your own alias for jamie. An alias is just
a name by which you refer to your public-private key pair.)
keytool -genkey -alias jamie -keyalg rsa
The keytool will prompt you for information that will be used to generate your self-signed certificate. Substitute your information for the information that I entered (indicated in bold). Use your domain name in place of your first and last name. Also, select a password that is different than mine.
Enter keystore password: 123456
What is your first and last name?
[Unknown]: jaworski.com
What is the name of your organizational unit?
[Unknown]: Software development
What is the name of your organization?
[Unknown]: James Jaworski
What is the name of your City or Locality?
[Unknown]: Chula Vista
What is the name of your State or Province?
[Unknown]: CA
What is the two-letter country code for this unit?
[Unknown]: US
Is <CN=jaworski.com, OU=Software development, O=James Jaworski, L=Chula Vista, ST=CA, C=US> correct?
[no]: yes
Enter key password for <jamie>
(RETURN if same as keystore password): 123456
The keytool will generate the key pair and self-signed certificate
and store them in a file named .keystore that is located
in the directory specified by the user.home Java system
property. You can use the following program to find the value of
user.home.
public class DisplayUserHome {
public static void main(String[] args) {
System.out.println(System.getProperty("user.home"));
}
}
The next step in obtaining your certificate is to submit a certificate signing request (CSR) to a certificate authority (CA). A CSR is a request to have the CA sign your self-signed certificate (thereby legitimizing it). When a CA signs your certificate, it tells the world that it has verified your identity and the fact that the certificate belongs to you. That way, when others use your signed JAR files, they will have a high degree of assurance that your JAR files were, in fact, signed by you, and not someone else posing as you.
You use keytool to create a CSR as follows. Substitute your alias
for jamie and your password for 123456.
keytool -certreq -alias jamie
Enter keystore password: 123456
-----BEGIN NEW CERTIFICATE REQUEST-----
MIIBvzCCASgCAQAwfzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRQwEgYDVQQHEwtDaHVsYSBW
aXN0YTEXMBUGA1UEChMOSmFtZXMgSmF3b3Jza2kxHTAbBgNVBAsTFFNvZnR3YXJlIGRldmVsb3Bt
ZW50MRUwEwYDVQQDEwxqYXdvcnNraS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPb5
Yt3M48Lwf2OjVYBG8+89HF35JB/YpHyyHt4DTohFeS2KbAQEvI03FGtG9KXZpzgumBttxhfiqRF8
6bF2GO8eDK1COubJ6ckEZziSlTUFYoLXqmLTui85TApXB8kJzj+SygQ2OP0APtVy6E3dq66izl89
RUzMdTH60QPxtbc5AgMBAAGgADANBgkqhkiG9w0BAQQFAAOBgQBEtAffkQVHRB8bGsm6yP7Sb8zZ
ert3h8pXdBlFjtC+SZZxUQq/rOGyqh1H320ZqJlcnmRBrgQth3KDh3WPXposnTt4eHwJKyK/whUk
0ucbkDo3cdidLLg4/as0QsVmje7udzcCdnCX6NuQqjvAayaOviU1i5GvN8ALbpWwbrf0uw==
-----END NEW CERTIFICATE REQUEST-----
The output of the keytool is your CSR. Redirect or copy it to a text file.
Now that you have a CSR, you need to get it signed by a recognized certificate authority. Although there are a number of CAs that will sign your certificate, I would suggest that you use Thawte Consulting or Verisign because their certificates are recognized by all browsers and have been proven to work with the Java plug-in 1.3. Of the two, I recommend Thawte because they provide excellent service and their certificates are about half the price of Verisign's.
If you decide to use Thawte, you can find out more information about obtaining an RSA code signing certificate. If you use Verisign, check out their information.
When your CA has verified your identity and signed your certificate. It will return a certificate or certificate chain in a standard text format (such as PKCS #7). The following is an example.
-----BEGIN PKCS #7 SIGNED DATA-----
MIIGhwYJKoZIhvcNAQcCoIIGeDCCBnQCAQExADALBgkqhkiG9w0BBwGgggZcMIID
QTCCAqqgAwIBAgIDB9BsMA0GCSqGSIb3DQEBBAUAMIHEMQswCQYDVQQGEwJaQTEV
MBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xHTAbBgNV
BAoTFFRoYXd0ZSBDb25zdWx0aW5nIGNjMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9u
IFNlcnZpY2VzIERpdmlzaW9uMRkwFwYDVQQDExBUaGF3dGUgU2VydmVyIENBMSYw
JAYJKoZIhvcNAQkBFhdzZXJ2ZXItY2VydHNAdGhhd3RlLmNvbTAeFw0wMTAxMjIy
MzAyNDNaFw0wMjAxMjIyMzAyNDNaMIGHMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
Q2FsaWZvcm5pYTEUMBIGA1UEBxMLQ2h1bGEgVmlzdGExFzAVBgNVBAoTDkphbWVz
IEphd29yc2tpMR0wGwYDVQQLExRTb2Z0d2FyZSBkZXZlbG9wbWVudDEVMBMGA1UE
AxMMamF3b3Jza2kuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM6Wku
ZYeoaEQVZWbKBLxbnID4N3wcDVsYAPDI/nIY5dnC2bFGyHNGCxEmeiAYdjb+rHuN
g2uhycZ1TtRNBOf9hnOw+NMyHAXytsIEf7wrf/H0WoAyvbZeG+sXrVMRpJJeCem0
BDAdairYkly/fdWIujlIa7mwVEBK9csgfIcutQIDAQABo3wwejAfBgNVHSUEGDAW
BggrBgEFBQcDAwYKKwYBBAGCNwIBFjARBglghkgBhvhCAQEEBAMCBBAwHQYDVR0E
BBYwFDAOMAwGCisGAQQBgjcCARYDAgeAMBcGA1UdEQQQMA6CDGphd29yc2tpLmNv
bTAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBBAUAA4GBADQdapQceZZ++qQJdSVT
i7wNFjDI72RkQzvGNWzmDg8mfIa7ZxsVCBblvOrCu9Ow8m1H+IJdyLTKLllXgo5M
zRIk8eB1+AY2H1MRI+G6fTudGCJbdfXS+G7ceGLf9HZ32gVIWvEJ682ihnefPsHE
W3WW05VtaTKidC0WAZAoe4h/MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQF
ADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UE
BxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYG
A1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQ
VGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRo
YXd0ZS5jb20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkG
A1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBU
b3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2Vy
dGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNl
cnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20w
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC
2oQl/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNk
CXDF/rFrKbYvScg71CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0
e982OsK1ZiIS1ocNAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN
AQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllD
fU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpa
PNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEcxAA==
-----END PKCS #7 SIGNED DATA-----
Once you receive your signed certificate from your CA, you need to import it into your keystore using keytool. I stored my certificate in the file thawtecert.txt before I imported it.
keytool -import -alias jamie -file thawtecert.txt
Enter keystore password: 123456
Enter key password for <jamie>: 123456
Top-level certificate in reply:
Owner: EmailAddress=server-certs@thawte.com, CN=Thawte Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
Issuer: EmailAddress=server-certs@thawte.com, CN=Thawte Server CA, OU=Certification Services Division, O=Thawte Consulting cc, L=Cape Town, ST=Western Cape, C=ZA
Serial number: 1
Valid from: Wed Jul 31 17:00:00 PDT 1996 until: Thu Dec 31 15:59:59 PST 2020
Certificate fingerprints:
MD5: C5:70:C4:A2:ED:53:78:0C:C8:10:53:81:64:CB:D0:1D
SHA1: 23:E5:94:94:51:95:F2:41:48:03:B4:D5:64:D2:A3:A3:F5:D8:8B:8C
... is not trusted. Install reply anyway? [no]: yes
Certificate reply was installed in keystore
That's all you need to do to obtain and install your RSA code
signing certificate. Now let's sign the scan.jar
file.
Using Your Certificate to Sign JAR Files
If you got to
this point and you still don't have an RSA code signing certificate,
don't worry, I'll show you how to sign scan.jar using my
certificate.
To sign scan.jar, use the following jarsigner
command. Substitute your alias for jamie.
jarsigner scan.jar jamie
Enter Passphrase for keystore: 123456
Enter key password for jamie: 123456
The jarsigner tool will replace scan.jar with a signed version of
the same file. The signature will use the public-private key pair
identified by the alias (jamie) and the signed
certificate associated with the key pair (the one that you received
from the CA).
You can also verify the JAR files signature using jarsigner:
jarsigner -verify scan.jar
If your scan.jar is properly signed it will respond
with "jar verified." Otherwise, it will respond with a message
indicating that the signature is missing or invalid.
Using HTMLConverter
Now that you have a signed JAR
file, you need to convert any HTML files that reference the applet so
that the applet executes with the Java plug-in. You do this using Sun's
HTML converter.
The HTML converter is packaged as a .zip file. Unzip
the file to a directory on your system.
In the converter/classes directory, you'll see two shell files
(HTMLConverter.bat and HTMLConverter.sh)
that are used to execute the HTML converter. Use
HTMLConverter.bat if you're running Windows and
HTMLConverter.sh if you're running Linux/Solaris.
When you run the shell file, the following window will open.
Select the directory containing scanner.htm and then click the
Convert button. The contents of the converted scanner.htm
will appear similar to the following.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"DTD/xhtml1-transitional.dtd">
<html>
<head><title>SimpleScannerApplet</title></head>
<body>
<div style="text-align: center">
<h1>SimpleScannerApplet</h1>
<!--"CONVERTED_APPLET"-->
<!-- CONVERTER VERSION 1.3 -->
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
WIDTH = "600" HEIGHT = "125" NAME = "ScanApplet"
codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
<PARAM NAME = CODE VALUE = "SimpleScannerApplet.class" >
<PARAM NAME = ARCHIVE VALUE = "scan.jar" >
<PARAM NAME = NAME VALUE = "ScanApplet" >
<PARAM NAME="type" VALUE="application/x-java-applet;version=1.3">
<PARAM NAME="scriptable" VALUE="false">
<COMMENT>
<EMBED type="application/x-java-applet;version=1.3"
CODE = "SimpleScannerApplet.class" ARCHIVE = "scan.jar"
NAME = "ScanApplet" WIDTH = "600" HEIGHT = "125"
scriptable=false pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html">
<NOEMBED></COMMENT>
Java not supported.
</NOEMBED></EMBED>
</OBJECT>
<!--
<APPLET CODE = "SimpleScannerApplet.class" ARCHIVE = "scan.jar" WIDTH = "600" HEIGHT = "125" NAME = "ScanApplet">
Java not supported.
</APPLET>
-->
<!--"END_CONVERTED_APPLET"-->
</div>
</body>
</html>
Deploying the Signed Applet
Having created and signed
scan.jar and converted scanner.htm using HTML converter, you're ready
to deploy these files. Put scan.jar in the same directory
as scanner.htm. You can also run the scanner from your local file
system using Navigator or Internet Explorer. In fact, it's a good idea
to do so, just to make sure that everything works as it should. The
following screen capture shows the scanner working in Internet
Explorer 5.5.
Jamie Jaworski is a Java security expert and author, focused on cryptography and such.
Return to ONJava.com.
Copyright © 2009 O'Reilly Media, Inc.