Friday, 17 June 2022

Sign a jar file using jarsigner tool

In this post, I am going to explain how to sign a jar file using jarsigner tool. ‘jarsigner’ tool is bundled as part of jdk distribution. To proceed with this tutorial, install jdk in your system.

 

Signing a jar file is a three step process.

a.   Create a public and private key pair

b.   Export the certificate to file system

c.    Sign the jar using jarsigner tool

d.   Verify the signed jar

 

Generate key pair

Syntax

keytool -genkey -alias {ALIAS_NAME} -keyalg {ALGORITHM_TO_GENERATE_KEY_PAIR} -keypass {KEY_PASSWORD} -storepass {STORE_PASSWORD} -keystore {KEY_STORE_FILE}

Example

keytool -genkey -alias keyPairToSignJar -keyalg RSA -keypass password123 -storepass password123 -keystore demo.jks

$ keytool -genkey -alias keyPairToSignJar -keyalg RSA -keypass password123 -storepass password123 -keystore demo.jks
What is your first and last name?
  [Unknown]:  java blogspot
What is the name of your organizational unit?
  [Unknown]:  bloggers
What is the name of your organization?
  [Unknown]:  https://self-learning-java-tutorial.blogspot.com/
What is the name of your City or Locality?
  [Unknown]:  Bangalore
What is the name of your State or Province?
  [Unknown]:  Karnataka
What is the two-letter country code for this unit?
  [Unknown]:  in
Is CN=java blogspot, OU=bloggers, O=https://self-learning-java-tutorial.blogspot.com/, L=Bangalore, ST=Karnataka, C=in correct?
  [no]:  y


Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore demo.jks -destkeystore demo.jks -deststoretype pkcs12".

Migrate the demo.jks file to pkcs12 by executing below command.

keytool -importkeystore -srckeystore demo.jks -destkeystore demo.jks -deststoretype pkcs12

bash-3.2$ keytool -importkeystore -srckeystore demo.jks -destkeystore demo.jks -deststoretype pkcs12
Enter source keystore password:  
Entry for alias keypairtosignjar successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

Warning:
Migrated "demo.jks" to Non JKS/JCEKS. The JKS keystore is backed up as "demo.jks.old".

When you list the content of this directory, you can see two files.

bash-3.2$ ls
demo.jks	demo.jks.old

 

Export the certificate to file system

Syntax

keytool -export -alias {ALIAS_NAME} -storepass {STORE_PASSWORD} -file {FILE_TO_STORE_THE_CERTIFICATE} -keystore {KEY_STORE_FILE}

Example

keytool -export -alias keyPairToSignJar -storepass password123 -file myCert.cer -keystore demo.jks

bash-3.2$ keytool -export -alias keyPairToSignJar -storepass password123 -file myCert.cer -keystore demo.jks
Certificate stored in file <myCert.cer>
bash-3.2$
bash-3.2$
bash-3.2$
bash-3.2$ ls
demo.jks	demo.jks.old	myCert.cer

Sign the jar using jarsigner tool

Syntax

jarsigner -keystore {KEY_STORE_FILE} -signedjar {SIGNED_JAR_NAME} {JAR_TO_SIGN} {ALIAS_NAME}

Example

jarsigner -keystore demo.jks -signedjar signed_hello.jar hello.jar keyPairToSignJar

Above command sign hello.jar file and generate signed_hello.jar file.

bash-3.2$ jarsigner -keystore demo.jks -signedjar signed_hello.jar hello.jar keyPairToSignJar
Enter Passphrase for keystore: 
jar signed.

Warning: 
The signer's certificate is self-signed.
bash-3.2$ 
bash-3.2$ 
bash-3.2$ 
bash-3.2$ ls
demo.jks		demo.jks.old		hello.jar		myCert.cer		signed_hello.jar

Verify the signed jar file

Syntax

jarsigner -verify {SIGNED_JAR_NAME}

Example

jarsigner -verify signed_hello.jar

bash-3.2$ jarsigner -verify signed_hello.jar

jar verified.

Warning: 
This jar contains entries whose certificate chain is invalid. Reason: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
This jar contains entries whose signer certificate is self-signed.
This jar contains entries whose signer certificate will expire within six months. 
This jar contains signatures that do not include a timestamp. Without a timestamp, users may not be able to validate this jar after any of the signer certificates expire (as early as 2022-09-15).

Re-run with the -verbose and -certs options for more details.

We can remove PKIX and other warning, by adding this self-signed certificate to the java cacerts file.


 

Add the self signed certificate to Java cacerts file

 

Syntax

keytool -import -v -trustcacerts -alias {ALIAS_NAME}  -file {CERTIFICATE_FILE} -keystore {CACERTS_FILE_PATH}

 

Example

keytool -import -v -trustcacerts -alias keyPairToSignJar  -file myCert.cer -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/Home/jre/lib/security/cacerts

 

Since this command require admin privileges to update cacerts file, I ran this command in sudo mode.

 

bash-3.2$ sudo keytool -import -v -trustcacerts -alias keyPairToSignJar  -file myCert.cer -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/Home/jre/lib/security/cacerts
Password:
Enter keystore password:  
Owner: CN=java blogspot, OU=bloggers, O=https://self-learning-java-tutorial.blogspot.com/, L=Bangalore, ST=Karnataka, C=in
Issuer: CN=java blogspot, OU=bloggers, O=https://self-learning-java-tutorial.blogspot.com/, L=Bangalore, ST=Karnataka, C=in
Serial number: 396d9471
Valid from: Fri Jun 17 14:59:01 IST 2022 until: Thu Sep 15 14:59:01 IST 2022
Certificate fingerprints:
	 SHA1: 0C:0E:F4:4A:14:85:92:4B:78:F2:6A:74:EB:FF:E5:E0:93:2D:A1:93
	 SHA256: 23:7E:DD:B1:BC:5F:92:24:4F:C1:55:9B:03:54:0E:7C:1C:18:F7:59:04:3C:18:08:EF:09:C4:A0:F8:00:3E:CE
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3

Extensions: 

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: F3 81 B5 68 6D F8 4D D9   69 DB 59 B9 77 04 23 58  ...hm.M.i.Y.w.#X
0010: 9F 83 9B FA                                        ....
]
]

Trust this certificate? [no]:  yes
Certificate was added to keystore
[Storing /Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/Contents/Home/jre/lib/security/cacerts]

‘changeit’ is the default password for cacerts file.

 

Let’s re verify the signed jar file.

bash-3.2$ jarsigner -verify signed_hello.jar

jar verified.

Warning: 
This jar contains entries whose signer certificate is self-signed.

Re-run with the -verbose and -certs options for more details.

You may like

Miscellaneous

Java cacerts file

Extract private and public key from keystore

Public, private key generation in Java

Export public key certificate from keystore

Read pkcs12 certificate information in Java

How to Get Client Certificate from HttpServletRequest

Programmatically import certificate to cacerts file in Java


 

 

No comments:

Post a Comment