Today's Question:  What does your personal desk look like?        GIVE A SHOUT

Using Java keytool programmatically

  Pi Ke        2016-01-09 06:28:07       23,657        14    

Java provides a command line tool to access and operate different keystore which store keys and certificates. This tool is named keytool and is located at \bin. 

On command line, you can issue below command to generate a keystore named mytest.jks which contains a private key and certificate chain.

keytool -genkeypair  -alias mykey  -keyalg RSA  -sigalg SHA256withRSA  -dname CN=Java  -storetype JKS  -keypass password  -keystore mytest.jks  -storepass password

Sometimes, in testing purpose, we may want to issue these command in our applications instead of start a command line terminal. This is doable since keytool itself is just a wrapper to some Java classes which do the actual keystore operations. The keytool will inetrnally invoke sun.security.tools.keytool.Main.main() method.

Hence in Java code, we can directly call this method to run the keytool, for example, to generate a keypair in keystore and list the keystore, we can write following code.

public class KeyToolTest {
	public static void main(String[] args){
		generateKeyPair();
		list();
	}
		
		
	// List keystore
	public static void list(){
		String command = " -list "+
						 " -v "+
	                     " -keystore mytest.jks "+
	                     " -storepass password";
		execute(command);
	}
	
	// Generate keypair
	public static void generateKeyPair(){
		String command = " -genkeypair "+
	                     " -alias mykey "+
	                     " -keyalg RSA "+
	                     " -sigalg SHA256withRSA "+
	                     " -dname CN=Java "+
	                     " -storetype JKS "+
	                     " -keypass password "+
	                     " -keystore mytest.jks "+
	                     " -storepass password";
		execute(command);
	}
	
	// Execute the commands
	public static void execute(String command){
		try{
			printCommand(command);
			sun.security.tools.keytool.Main.main(parse(command));
		} catch (Exception ex){
			ex.printStackTrace();
		}
	}
	
	// Parse command
	private static String[] parse(String command){
		String[] options = command.trim().split("\\s+");
		return options;
	}
	
	// Print the command
	private static void printCommand(String command){
		System.out.println(command);
	}
}

The only thing needs to be taken care of is that sun.security.tools.keytool.Main.main() receives a set of options of the command instead of taking a string command.  You can issue other commands as well with above logic.

JAVA  KEYTOOL 

Share on Facebook  Share on Twitter  Share on Weibo  Share on Reddit 

  RELATED


  14 COMMENTS


Anonymous [Reply]@ 2016-09-15 08:31:10

Unfortunately in Java 8

sun.security.tools.keytool.Main

is not API ..

Ke Pi [Reply]@ 2016-09-15 09:44:29

Yes. Because it's a sun.* package which is an internal package and it may not be supported in the future. In Java 8, I think you can still use reflection to do this.

Anonymous [Reply]@ 2018-02-05 16:18:52

Useless post!

Ke Pi [Reply]@ 2018-02-06 05:27:04

Really hate this kind of comment. Do no good to anyone. You should give reason or suggestion on the post if you have any problem with it instead of just blindly criticizing something.

Anonymous [Reply]@ 2023-09-15 09:27:29

Useless comment

Anonymous [Reply]@ 2018-03-28 16:13:49

Good post , It would be more nice if you can modify on how to add the Organization name , First name Last name Etc ... 

Anonymous [Reply]@ 2018-03-28 18:15:18

Is there any way we can add email except importing a certificate 

Ke Pi [Reply]@ 2018-03-29 08:49:54

You mean add organization name to certificate?

Anonymous [Reply]@ 2018-03-30 08:52:21

Good post, is there any way to get expiration date of every certificate in the keystore?

Ke Pi [Reply]@ 2018-03-30 09:36:42

Keytool itself doesn't provide this capability. Below are two possible solutions for your reference.

  1. Using keytool to list all entries and then use grep command
    keytool -list  -v  -keystore mytest.jks  -storepass password | grep "Valid from"
  2. Do it programatically. Convert the certificate to a X509Certificate and then call the getNotAfter() method
    ((X509Certificate)cert).getNotAfter()

If you want to know how to operate a keystore in Java, you can refer to https://www.pixelstech.net/article/1408345768-Different-types-of-keystore-in-Java----Overview

Anonymous [Reply]@ 2018-06-26 22:10:45

Good Post, It help me much! Is there better way to create CSR in java 8, since java 8 remove the sun.security package?

Ke Pi [Reply]@ 2018-06-30 06:25:50

You can refer to this post for creating CSR in Java https://www.pixelstech.net/article/1464167276-Generating-CSR-using-Java

CT [Reply]@ 2019-04-09 10:54:35

excellent post, is there a possibility to add the "YES" answer in the params?

 

Anonymous [Reply]@ 2021-03-15 07:33:35

The KeyStore Java API can also be used without needing to create a child process via Command. See

https://docs.oracle.com/javase/9/docs/api/java/security/KeyStore.html