简体   繁体   中英

keytool command successful on command line but not via ProcessBuilder

I am trying to use keytool to generate a certificate programmatically. In order to do that, I am first generating a keystore using the following command:

-genkeypair -alias alias -keyalg RSA -keysize 2048 -dname "CN=name,OU=ou,O=o,c=pt" -validity 365 -keystore teststore.jks -keypass testpass -storepass testpass -noprompt

On the command line this completes successfully, creating the file teststore.jks without asking for the user's input. I need this since I will be using this command from a ProcessBuilder instance.

I use the following code to generate the same command:

StringBuilder command = new StringBuilder();
command.append("keytool ");
command.append("-genkeypair");
command.append(" -keystore " + username + "store.jks");
command.append(" -alias " + username);
command.append(" -keyalg RSA");
command.append(" -keysize 2048");
command.append(" -dname \"CN="+username+", OU=FCT, O=UNL, L=Unknown, ST=Unknown, C=PT\"");
command.append(" -validity " + 365);
command.append(" -keypass " + certpassword);
command.append(" -storepass " + certpassword);
command.append(" -noprompt");
ProcessBuilder pb = new ProcessBuilder(command.toString());
pb.inheritIO();
pb.start();

When I run the program, I get the following output:

java.io.IOException: Cannot run program "keytool -genkeypair -keystore teststore.jks -alias alias -keyalg RSA -keysize 2048 -dname "CN=name, OU=ou, O=o, C=pt" -validity 365 -keypass ssc1415 -storepass ssc1415 -noprompt": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at UserRegistry.main(UserRegistry.java:29)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:185)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 1 more

Since I use pb.inheritIO() I commented out the -dname and the -noprompt parts and it still terminated with the same error, so I ran out of ideas.

I succeeded in working around this issue by supplying a String[] and using the getRuntime().exec() method.
I used:

// Generate key for keystore
String userStore = username + "KeyStore.jks";
String userDetails = "CN=" + username
        + ", OU=FCT, O=UNL, L=Unknown, ST=Unknown, C=PT";
String certValidity = "" + 365;
String keytoolArgs[] = { "keytool", "-genkeypair", "-alias",
        username, "-keystore", "Client/" + userStore,
        "-keypass", certpassword, "-storepass", certpassword,
        "-keyalg", "RSA", "-keysize", "2048", "-dname",
        userDetails, "-validity", certValidity };
System.out.println(Arrays.asList(keytoolArgs));
Process p1 = Runtime.getRuntime().exec(keytoolArgs);
p1.waitFor();  

This enabled me to create a key with dynamic arguments passed in to a program, which in my project made it easier to build multiple certificates at once.

Please note that while creating command array in ProcessBuilder you need to specify each not white space argument as a separate command object. White spaces are NOT allowed inside arguments.

For example this will not work

command.append(" -alias " + username);

This should be written as (also the value should be a separate argument)

command.append("-alias");
command.append(username);

Please try with this code

StringBuilder command = new StringBuilder();
command.append("keytool");
command.append("-genkeypair");
command.append("-keystore");
command.append(username);
command.append("store.jks");
command.append("-alias");
command.append(username);
command.append("-keyalg");
command.append("RSA");
command.append("-keysize");
command.append("2048");
command.append("-dname");
command.append("CN="+username+",OU=FCT,O=UNL,L=Unknown,ST=Unknown,C=PT");
command.append("-validity");
command.append("365");
command.append("-keypass");
command.append(certpassword);
command.append("-storepass");
command.append(certpassword);
command.append("-noprompt");
ProcessBuilder pb = new ProcessBuilder(command.toString());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM