0

I am trying to add a private key pair to an existing Java KeyStore file. When I execute the following command via the Terminal, it works. (ie. when I execute "keytool -list -v -keystore ecekeystore.jks", I can see the newly added key)

keytool -genkey -alias blabla -keyalg RSA -keystore ecekeystore.jks -dname "CN=MyName, OU=blabla, O=blabla, L=blabla, S=blabla, C=US" -storepass password1 -keypass password2

But when I run the following piece of Java code, nothing changes in my keystore file.

    try {
        Runtime rt = Runtime.getRuntime();
        String command = "keytool " +
                "-genkey -alias blabla -keyalg RSA " +
                "-keystore ecekeystore.jks " +
                "-dname \"CN=MyName, OU=blabla, O=blabla, L=blabla, S=blabla, C=US\" " +
                "-storepass password1 " +
                "-keypass password2";
        System.out.println(command);
        Process pr = rt.exec(command);
        return true;
    } catch (IOException e) {
        e.printStackTrace();
    }

I'd appreciate any help!


SOLVED:

    Runtime rt = Runtime.getRuntime();
    try {
        String[] cmdArray = new String[14];
        cmdArray[0] = "keytool";
        cmdArray[1] = "-genkey";
        cmdArray[2] = "-alias";
        cmdArray[3] = "blabla";
        cmdArray[4] = "-keyalg";
        cmdArray[5] = "RSA";
        cmdArray[6] = "-keystore";
        cmdArray[7] = "ecekeystore.jks";
        cmdArray[8] = "-dname";
        cmdArray[9] = "CN=MyName, OU=blabla, O=blabla, L=blabla, S=blabla, C=US";
        cmdArray[10] = "-storepass";
        cmdArray[11] = "password1";
        cmdArray[12] = "-keypass";
        cmdArray[13] = "password1";

        Process pr = rt.exec(cmdArray);

        InputStream is = pr.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String line;

        System.out.printf("Output is:\n");

        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }

        return true;
    } catch (IOException e) {
        e.printStackTrace();
    }
  • 1
    This is a programming question, not a security question. It looks to me like `Process.exec` requires arguments to be specified in a separate array parameter. – AndrolGenhald Apr 23 '18 at 18:29
  • I followed the documentation here (https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html), it says the only input is the String 'command'. – Ece Tanova Apr 23 '18 at 18:36
  • "This is a convenience method. An invocation of the form exec(command) behaves in exactly the same way as the invocation exec(command, null, null)." Also I hope it's clear that I meant `Runtime.exec` previously. – AndrolGenhald Apr 23 '18 at 18:47
  • Are you in the proper directory? The `-keystore` is a relative path, so if you're not in the appropriate directory... – Jim Garrison Apr 23 '18 at 19:04
  • I tried specifying the working directory with 'Process pr = rt.exec(command, null, dir);' but nothing changed. – Ece Tanova Apr 23 '18 at 19:20
  • @AndrolGenhald It seems that the 'env' input is for changing environment variables such as PWD, HOME, SHELL, etc. Could you clarify how to use those things in this case? – Ece Tanova Apr 23 '18 at 19:30
  • You are correct, I looked at it too quickly and misinterpreted. There is [this](https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#exec(java.lang.String[])) however which looks like what you need. – AndrolGenhald Apr 23 '18 at 19:44
  • `Runtime.exec(String)` splits at whitespace; it is not a shell and does not parse like a shell and in particular **cannot handle commandline containing quotes**. Use the `exec(String[])` overload, or `ProcessBuilder`. And you should always wait for the process to complete and check its output, which would have told you about the problem 7 hours ago. – dave_thompson_085 Apr 24 '18 at 02:13
  • @dave_thompson_085, thank you! Using exec(String[]) did it, and I am also checking for output now. – Ece Tanova Apr 24 '18 at 06:31

0 Answers0