Digital code-signing, based on industry standard PKI technology standards, is a powerful approach for
secure distribution of software over the Internet with authentication and integrity verification capability.
This technology also facilitates more
powerful web-based client-side applications which rely on the end user making a trust decision in the
downloaded software, particularly for signed Java applets, installable ActiveX controls etc... However, the situation
for developers is complicated by various approaches, tools and implementations of code-authentication
verification, the main approaches being Microsoft Authenticode (based on cryptoAPI win32technology),
Netscape based "object signing" and Sun Java code signing. Each of these vendors offer different
tools and technologies, with generally incompatible "keystore" implementation technologies for key/certificate storage,
even though code signed with each technology involves some elements that are based on public PKI
standards (e.g. pkcs#7 signature blocks, X509v3 certificates etc..).

This document describes how a *single* code signing certificate can be used with the
three vendor technologies and tools to sign code targeting Microsoft Authenticode (signed cabs, exe, dll, ocs etc..), Netscape
(signed applets in JARs) and Sun (signed JARs for JavaPlugin, Netscape etc..).
Only one particular type of commercial certificate has been tested for this "3-ply" capability.

The Authenticode Process
[Note:
The Thawte certificate registration process for IE (Authenticode) currently generates ONLY 512 bit RSA long key, which
is generally viewed as inadequate from a security perspective. This problem arises from inadequate implementation of the Microsoft
"Enrollment Control" (an ActiveX Control) used by the web-page for key generation/registration. The process for Netscape and Java key
registration however generates larger RSA keys.]

Apply for the Thawte Authenticode (Multi-purpose Certificate) Developer code-signing certificate at the Thawte web site.
Use Internet Explorer 5+ during the process and follow the
installation instructions
VERY carefully. In particular, specify a file path when asked for a location to store your automatically-generated
private key, otherwise it will be stored in the win32 registry automatically. This will allow greater flexibility for code signing
with Authenticode and provides a better understand of the Authenticode processes.

When your issued certificate has been approved, download the public certificate component from the Thawte site, as instructed
by email sent to you. Keep the public and private key files (typically in .pvk and .spc file types) in a safe place.
Back-up these key-sets several times and store in different physical locations.

Use the Microsoft pvkimprt.exe utility to now import
the public and private key into the win32 registry. This provides greater convenience for code-signing with Microsoft
Authenticode, and will make the public and private key available for "export" out of the Authenticode world.
[Alternatively,it is possible to directly use the .spc and .pvk cert/key files to generate the pkcs12 file as described in
the pvkimprt documentation].
Generating a standard pkcs12 protected key/cert container file is a required step for moving your public/private key
information to Netscape and Sun environments.
Note that you must install and run pvkimprt.exe with administrator privileges on Win2000+. To use the
code-signing certificate with Authenticode technology, obtain the
Authenticode 5 Tools which are
designed to work with components installed with Internet Explorer 5+. Similar tools of similar version are also distributed with the
Microsoft Platform SDK in its bin directory.
If you wish to sign Java code, you must also install the
Microsoft SDK for Java, Version 4.0 (the final version
available).

Once the Authenticode tools are installed, you can sign code (exe, dll, ocx etc..) using either your two key files: signcode -spc mycert.spc -v mykey.pvk -t http://timestamp.verisign.com/scripts/timstamp.dll myapp.exe
or you can use the "Common Name" of your public certificate to access the same key information in the win32 registry:signcode -cn "Your Common Name" -t http://timestamp.verisign.com/scripts/timstamp.dll myapp.exe
where both examples include the -t option to "time stamp" the signature (requiring Internet connectivity).

To make the keys/certificate available for use with Netscape "object signing" technology, you simply export you public and
private keys together in one step using Internet Explorer menu selection: Tools | Internet Options | Content | Certificates | Personal
and select your certificate and EXPORT it. Select the option to include the private key. Select to protect
the resultant .pfx file with the highest security (requiring a password for subsequent importing to any other environment).
When the file is generated (say myIEexport.pfx), you now have a standard "PKCS#12" format password-protected key
container which contains all the encrypted information of your public and private keys and certificate information. Back
this file up several times.
To import the keys/cert into Netscape, use the menu selection (Netscape 4.76):Communicator | Tools | Security Info | Yours
and click "Import a Certificate". This will access the Netscape keystore files, and if this is the first time, you will
be required to enter a password to protect THAT keystore (and will be asked to re-enter it). Then you will be
asked for a file to import. Browse to select myIEexport.pfx, enter the password protecting that file and the
import should succeed. Unfortunately, this process assigns a cryptic nick-name to the certificate in Netscape, the
name you will use in the signtool command line below.
To use the Netscape environment to sign code (for Netscape deployment, or to sign code for JavaPlugin deployment),
obtain the netscape
signtool1.3 tool.
Follow the Netscape documentation to use your Netscape cert and key
files (key3.db and cert7.db) with signtool.exe. A typical signing command, which combines JAR archiving and signing
in one step is: signtool -k "b1345-somecryptic-l432537" -d cacertdb -Z mynew.jar signingdir

Porting To Sun Java Environment

To also make the keys/certificate available for use with Sun's Java code-signing technology, the keys/cert must now be
contained in a PKCS#12 container which can be properly recognized by your Sun j2se environment. Unfortunately earlier
versions of j2se (versions <= 1.3.1) ONLY recognize PKCS#12 files exported by Netscape and NOT those exported by
Internet Explorer. At the present time, j2se v 1.4 b3 does recognize IE-exported PKCS#12 files (including keytool.exe and
the jsse api included with j2se v1.4 b3). Thus, for j2se v1.4 b3+, simply use the myIEexport.pfx file exported above from IE directly with
the keytool and jarsigner as a PKCS#12 keystore.
For j2se v1.3.x, Netscape must be used to generate a PKCS#12 file recognized by keytool, jarsigner :
From Netscape using the menu selection (Netsape 4.76): Communicator | Tools | Security Info | Yours
and click "Export". You are required to enter the Netscape Database keystore password, and then you must choose a password (and re-enter
for verification) to protect the exported file, say mynnexport.p12. This file is again a PKCS#12 format key container which
will be recognized directly by the Sun j2se tool keytool.exe as a keystore file of type pkcs12.

To use Sun tools with either j2se v1.3.x and the exported mynnexport.p12, or
j2se v1.4 b3+ and the exported myIEexport.pfx, the keytool.exe and jarsigner.exe utilities need support for the pkcs12 keystore provider.
This is currently available in at least three different configurations:
(j2se v1.3 + jsse 1.0.2), (j2se v1.3 +j2ee v1.3), or j2se v1.4+
where j2se == "Java 2 Standard Edition"
, jsse == Java Secure Socket Extension
, j2ee == Java 2 Enterprise Edition

For the illustrative example below, j2se v1.3.1 was used and the j2ee v1.3
archive "j2ee.jar" was added into the j2se v1.3 ext (extensions) directory and the java.security file
was updated with the new pkcs12 provider information as discussed in the jsse 1.0.2 install instructions.
[Note: this step is not required if using j2se v1.4+].
Note that both the j2sdk and j2re environments (ext directory modification and java.security file modification)
must be changed since the tools like keytool and jarsigner use j2sdk paths like:C:\jdk1.3.1\jre\lib\ext
whereas deployed examples (say with JavaPlugin etc..) use j2re paths like:C:\Program Files\JavaSoft\JRE\1.3.1\lib\ext

To verify that your configuration is correct, ensure that you can read the Netscape-exported keystore file: keytool -list -storetype pkcs12 -keystore mynnexport.p12
which should show a single entry in this pkcs12 keystore file.

Alternate Procedure (advanced)
It is also possible to directly import the public/private key from the Netscape-exported pkcs12 file (for j2se v1.3.x) or from
the IE-exported pkcs12 file (for j2se v1.4 b3+) into a
j2se JKS type keystore and to rename the alias to a more meaningful name than that imposed by IE/Netscape.
Again, the jsse support for pkcs12 keystore provider is required as described above.
The java.security.KeyStore class methods
(load, getInstance, aliases, setCertificateEntry, setKeyEntry etc..) can
be used in a simple Java application to transfer the keys from a pkcs12 file
to an existing JKS keystore thus conveniently consolidating all code-signing keys for j2se code-signing within one keystore.
A
KeystoreMove.java simple code sample
is available based on a Java Developer Connection code snippet.
This utility provides a prompt during the key-copy operation, to change the key alias from the source keystore to something more meaningful
in the destination keystore.
An alternate way of changing the alias name is available using the keytool -keyclone ... option (which simply
duplicates the private key and certificate chain in the Sun keystore): keytool -keyclone -alias "b1345-somecryptic-l432537" -dest "thawtemig" -keystore .keystore

3rd Party Solutions:

Currently, at release j2se v1.4 b3, the Sun keystore provider implementation does not include the ability to WRITE
pkcs12 keystores. Thus keys generated with keytool.exe into a JKS type keystore cannot be written out to a pkcs12 keystore file, either
with keytool.exe or using the standard API. However, a freely available (see license)
jce provider implementation which DOES support writing pkcs12
stores is available via Legion of the BouncyCastle. Uwe Guenther has written a Java application utility
BCMain.java which exports a user-specified JKS keystore to a pkcs12 file which can
subsequently be imported into either Microsoft Authenticode or Netscape object-signing key/cert stores essentially completing the "reverse porting"
process, complementing the information presented previously on this page.
To use the "Bouncy Castle Provider" extension, download the relevant JDK 1.x bcprov-jdk1x-112.jar archive and place
it in the following extension directory locations (one for compiler visibility, one for runtime visibility):

${jdk.home}/jre/lib/ext/
${java.home}/jre/lib/ext/

The sample code can be compiled with j2se v1.3.1, but requires jce to execute.
Jce is included with j2se v1.4+ but must be added as an extension to j2se v1.3.x.
Note that the BouncyCastle provider is only being used here to export the keys from JKS to PKCS12 keystores.
The code-signing process using jarsigner.exe and RSA keys is of course
fully supported by j2se v1.3.
The "Bouncy Castle" jse provider has been verified to work with j2se v1.4b3, but j2se v.1.3.1 cannot properly read the exported pkcs12 file.
The advantage of using the Sun keytool.exe for key generation and PKCS10 Certificate Request processing is that
RSA key strengths up to 2048 bits can be generated with the j2se keytool, and the Thawte/Java key registration process correctly
handles this key strength (see note above on current Thawte/Authenticode IE 512 bit generation process limitation).
Further, test (self-signed) certificates
can be generated with keytool.exe and then, after exporting to pkcs12 keystores using this 3rd party jse provider, used with MS Authenticode signcode.exe
or Netscape signtool.exe, as an alternative to using test certificates generated by these vendors.

A simple self-signed example:
j2se v1.3.1 was used to generate a new 2048-bit RSA self-signed certificate:

This key was exported to a pkcs12 store file mig.p12 using the sample java application BCMain.java above. This pkcs12 file, mig.p12 was imported into
"Personal" Authenticode store (by double-clicking it) . The
Authenticode 5 tool signcode.exe was then used in GUI mode
to sign a simple win32 application sguitartuner.exe (a little guitar tuner utility for Win2000, XP) successfully.
If this application is downloaded using IE4+, then
a security dialog appears prompting the user to Open, Save or Cancel the download. If Open is selected, a Security
Warning dialog appears (screen shop), indicating that the "authenticity of this content cannot
be verified, therefore it cannot be trusted". This is because the code was signed with a self-signed certificate which
is its own root CA, which most end users will not have installed (in a real issued Thawte/Verisign certificate, the certificate and
signature would be trusted since the root CA issuer would already be present in the "Trusted Root Certification Authorities" list. However,
the end user would still be prompted with a choice to trust subsequent code (without any prompting) signed with the same certificate.).
If one of the links in the Security Warning panel is clicked, it allows the end user to view the certificate
contents and potentially import the public certificate included with the signature within the .exe file.
(Note: be extremely cautious about doing this for a ROOT CERTIFICATE).