Cross Platform Code Signing

Code Signing

I recently decided to enhance my software’s professionalism and improve my users’ experience, by signing my software applications. My goal was to be able to sign my windows executables (.exe), Java applets and jar, (.jar) files and Mac .app bundles. By signing my code I could assure my customers of the authenticity of my software, and help ensure the integrity of the files.

Computer CodeIn this article I won’t discuss the process of applying for a certificate, but rather will describe how to use that certificate to sign code on Windows, Mac and for Java. To start, you need a code signing certificate; I decided to purchase one through KSoftware (which is a reseller of Comodo certificates). After going through the application process and paying my fee, I ended up with two files; a Private Key (.pvk) file (with a password I specified during the application process) and a PKCS #7 Certificate file (.spc). You may end up directly with a PKCS #12 (.pfx) file, but I will describe how to start with a .pvk and .spc file.

Tools Required

There are many different steps and tools required to go from the original .pvk and .spc files, to the final signing of .jars, .exes and .apps. Below is a list of the tools I mention in this article. See the references section for where to download them from.

Tool Description Provider Location
pvk2pfx tool to convert a .pvk and .spc to a .pfx Microsoft SDK <Microsoft SDKs>Windows\vx.x\Bin
signtool tool to sign an .exe Microsoft SDK <Microsoft SDKs>Windows\vx.x\Bin
keytool tool to create and manage Java Keystores Oracle Java SDK <Java JDK>/bin
pkcs12import tool to import .pfx into a Java Keystore Java Web Services Developer Pack Sun/jwskp-2.0/xws-security/bin
jarsigner tool to sign .jar files Oracle Java SDK <Java JDK>/bin
Keychain Access application to manage Keychains on Mac OS X Mac OS X /Applications/Utilities
codesign tool to sign .app bundles on Mac OS X Mac OS X /usr/bin/codesign

PVK and SPC to PFX

There are many code signing tools available, (see references below), and many of them require a .pfx (PKCS #12) file, so the first thing to do is create a .pfx file from the .pvk and .spc files. The Microsoft SDK provides a tool called pvk2pfx which provides this functionality. According to the Microsoft Documentation its usage is as follows.

Example:

This command takes mypfkfile.pvk and myspcfile.spc and creates mypfxfile.pfx which has a password of mypfxpassword. (Note: you can optionally make the .pfx password the same as the .pvk password).

Signing Windows Files (on Windows only)

Now that you have a .pfx file, you can sign your Windows code (e.g .exe files). There are several tools available to do that (some with a GUI), but the basic way is to use signtool.exe from the Microsoft SDK. The usage is as follows:

Example:

This command signs myWindowsFile.exe and time stamps with a time stamp provided by Comodo time stamping server. This can be also done as part of an ant build script as follows:

The property ${microsoftSDK} is defined as follows

This assumes the build file, .pfx and .exe are all in the same location and the build file is run from that location.

Java Keystore

Before you can sign a Java .jar file, a little more up front work is needed. Java .jar files are signed using keys contained in a keystore. A Java keystore is a file that contains a set of keys, so what we need to do is either add our certificate to an existing keystore, or create a new keystore to add it to. I decided to create a new keystore that will be used just for signing my .jar files. The Java SDK provides a utility called keytool.exe which provides the functionality of managing keystores. Unfortunately, its seems like you can’t create an empty keystore directly, but you need to provide an initial key when creating it. To work around this, you can just create a keystore with a temporary, self signed, key, and then later delete the temporary key. You can create the keystore with the following:

This command creates a key with alias temp, and password temporary, and then creates a keystore called mykeystore.keystore with password mykeystorepassword, and adds the key to the keystore. With the next command, the key with alias temp, is deleted from the keystore, and you end up with an empty keystore ready for your certificate key.

Adding certificate to Java Keystore

Now you have an empty Java keystore, so next you need to add your certificate to it. This can be done using pkcs12import, which is provided as part of the Java Web Services Developer Pack. The command is as follows:

This imports mypfxfile.pfx into the keystore and secures it with the password mypfxpassword (in this case I gave the key in the keystore the same password as the .pfx file it came from, to keep things easier, but you can give it any password you want).

Signing a .jar file

Now with your certificate in your keystore, you can finally sign a .jar file. The Java SDK provides the tool jarsigner, to accomplish this:

This command signs a jar called myJar.jar using the key with alias mykeyalias with password mypfxpassword contained in the keystore mykeystore.keystore with a password of mykeystorepassword. This can also be done from an ant build script as follows:

This assumes the build file, keystore, and .jar file are all in the same location and the build file is run from that location.

Signing Mac .app bundles (on Mac OS/X only)

To apply code signing on a Macintosh system, you need to add your code signing certificate, to a Mac keychain. A keychain on Mac, is somewhat similar to the Java keystore; it is a repository of various certificates, passwords and other information that needs to be secure. The easiest way to add a certificate to a keychain, is it to double-click on a .pfx file, on a Mac computer, and it will automatically be imported into your user’s default keychain (note: you will be requested for the password of your .pfx file). Alternatively, you can you the Keychain Access application to import you certificate. Now, to sign an .app you use the codesign command that comes with the Mac OS/X Developer tools. The basic usage for this command is as follows:

Where identity is the name (CN) from your certificate which can be found by viewing your certificate in the Keychain Access app. Example:

This will sign the application bundle called myApp.app using a Certificate with the identity of My Name, found in the default keychain. This can also be done from an ant build script as follows:

Flowchart

Below is a flowchart that summarizes the steps required for signing .exe, .jar and .app Code Signing Flow Chart

References

Note: this article first appeared in the December 2010 Issue (Volume 23, No. 12) of ASPects, The Monthly Newsletter of the Association of Shareware Professionals.

The following two tabs change content below.

Victor Ewert

Proprietor/Developer at Ewert Technologies
I am Victor Ewert, a Software Developer and owner of Ewert Technologies. In the past I have worked as a Software Tester including working on Software Test automation. My current technology interests include Java, JavaFX, Swift, Privacy and Security, and Mobile App development.

Latest posts by Victor Ewert (see all)

One thought on “Cross Platform Code Signing

  1. Work great on the GUI, however, it doesn’t work well with conammd line. For example, the -p option will takes any files without any errors, and even with the right proj.ppe file, it didn’t convert the obfuscate the assembly. Every time the code is compiled, it seems to change the checksum value stored in the ppe file. As a result, because of the mismatch checksum, the assembly does not obfuscate. Please help.

Leave a Comment