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 thejar/
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. 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
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}