How to sign jar files

· 477 words · 3 minute read

Danger

I encountered the error of the jarsigner missing from my path. This error occurs if the jre is installed not the jdk. To fix this, install the jdk and set it as your default.

On Arch linux:

1pacman -S jdk-openjdk
2archlinux-java set java-19-openjdk

You should now be able to run the jarsigner and the keytool.

Generating the keystore ##

Warning

Make sure your jar is built and in the jar/ directory.

To generate the keystore run the following command in the parent directory to the jar/ directory:

1# unix
2keytool -genkey -alias server -keyalg RSA -keysize 2048 -keystore keystore.jks
3# windows
4# change the version to the jdk you're using
5"C:\Program Files\Java\jdk-17.0.5\bin\keytool" -genkey -alias server -keyalg RSA -keysize 2048 -keystore keystore.jks

Enter the required data.

keystore output

Now check if the key was generated correctly using the following command:

1# unix
2keytool -v -list -keystore keystore.jks
3# windows
4# change the version to the jdk you're using
5"C:\Program Files\Java\jdk-17.0.5\bin\keytool" -v -list -keystore keystore.jks

keystore view

Signing the jar ##

After having generated the keystore and viewed if it contains our certificate we are now good to go for signing our jar.

Run the following commands to first sign the jar and afterwards verify the certificate:

Warning

Replace <yourpassword> and <yourjar>.jar with the password you choose while generating the keystore and the name of the jar you want to sign.
1# unix
2jarsigner -keystore keystore.jks -storepass <password> ./jar/<yourjar>.jar server
3jarsigner -verify -keystore keystore.jks -storepass <password> jar\<yourjar>.jar server
4
5# windows
6# change the version to the jdk you're using
7"C:\Program Files\Java\jdk-17.0.5\bin\jarsigner" -keystore keystore.jks -storepass <password> ./jar/<yourjar>.jar server
8"C:\Program Files\Java\jdk-17.0.5\bin\jarsigner" -verify -keystore keystore.jks -storepass <password> jar\<yourjar>.jar server

Verify certificate programmatically ##

Per convention you should use a factory to build a component which was loaded from a jar. To verify if the component is signed before loading it into the program insert the following function in your factory and call it before loading the component in your application.

 1public class ExampleFactory {
 2    public static boolean verify(String pathToJar){
 3        String curOs = System.getProperty("os.name");
 4        boolean isVerified = false;
 5
 6        ProcessBuilder pb = null;
 7
 8        // call the jarsigner depending on the operating system
 9        if(curOs.startsWith("Linux")){
10            pb = new ProcessBuilder("jarsigner", "-verify", pathToJar);
11        } else if(curOs.startsWith("Windows")){
12            pb = new ProcessBuilder("C:\\Program Files\\Java\\jdk-17.0.5\\bin\\jarsigner", "-verify", pathToJar);
13        } else {
14            return isVerified;
15        }
16
17        // go through the output of the jarsigner command and return true if the "verify" is in any of the lines
18        try {
19            Process p = pb.start();
20            InputStream iS = p.getInputStream();
21            InputStreamReader iSR = new InputStreamReader(iS);
22            BufferedReader bR = new BufferedReader(iSR);
23
24            String line;
25            while((line = bR.readLine()) != null){
26                if (line.contains("verified")){
27                    isVerified = true;
28                }
29            }
30        } catch(Exception e){
31            e.printStackTrace();
32            return isVerified;
33        }
34
35        return isVerified;
36    }
37}