0

I am trying to write something in Java to automatically import a certificate. When entering this command in the command shell:

    keytool -import -keystore c:\.truststore -alias xenv -file cacert.pem

it asks me for 2 questions: the password and if I want to confirm. In Python, I can use subprocess.Popen as follows:

p = subprocess.Popen("keytool","-import","-keystore","c:\\.truststore","-alias","xenv","-file","cacert.pem", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
stdout, stderr = p.communicate("password\n" + "y\n")

I am now attempting to do something similar in Java. I think I'm on the right track after a few hours of playing around, but I can't quite get it to work. Any idea what I am doing wrong? Thanks in advance!

import java.io.*;

public class PropertyTest {

    public static void main(String[] args) throws IOException {
        ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "keytool", "-import", "-keystore", "c:\\.truststore", "-alias", "xenv", "-file", "c:\\cacert.pem");
        pb.redirectErrorStream(true);
        Process p = pb.start();
        OutputStream out = p.getOutputStream();
        out.write("password\n".getBytes());
        out.write("y\n".getBytes());
    }
}
4
  • Why? You can provide the password as a parameter, and you can eliminate the confirmation prompt with another parameter. And you can eliminate the whole thing by using the KeyStore class. Commented Jul 10, 2014 at 0:37
  • In this simplified example you can pass in the password as a parameter, but there are a bunch of cases when using keytool or openssl that you must confirm things such as the organizational unit, etc. and you cannot pass those confirmations in as a parameter. Commented Jul 10, 2014 at 1:08
  • That is simply untrue. You can pass in everything as a parameter to the keytool, and you can also use the KeyStore API directly and avoid the whole problem. You're going about this quite the wrong way. Commented Jul 10, 2014 at 1:10
  • Ok, forget the keytool example. The question is on how to pass in user input in general using a similar manner to C and Python's pOpen. Do you know how? Commented Jul 10, 2014 at 2:14

1 Answer 1

1

This worked. I changed it to a BufferedWriter and flushed and closed it when I was done. Hopefully this helps someone else out who is stuck on a similar problem!

    ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "keytool", "-import", "-keystore", "c:\\.truststore", "-alias", "alias", "-file", "c:\\cacert.pem");
    pb.redirectErrorStream(true);
    Process p = pb.start();
    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
    out.write("allgoodthings\n");
    out.write("y\n");
    out.flush();
    out.close();
Sign up to request clarification or add additional context in comments.

2 Comments

You don't really need the BufferedWriter. The close may have helped, the flush almost certainly.
You're right. I just tested with an OutputStream and it worked too. Removing the flush actually did nothing though (nothing visible at least), but it will not work without the close.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.