質問

I'm trying to execute a gpg-command in Java to create a new Keypair, but I'm not getting an answer from the console. My code works well if I try to execute a gpg-command for the version gpg --version or to retrieve the keylist with gpg --list-key.

I'm using code from another Stackoverflow-Question:

public void getKeyList(){
    try {

        Process gpgProcess = Runtime.getRuntime().exec("gpg --gen-key");

        BufferedReader gpgOutput = new BufferedReader(new InputStreamReader(gpgProcess.getInputStream()));
        BufferedWriter gpgInput = new BufferedWriter(new OutputStreamWriter(gpgProcess.getOutputStream()));
        BufferedReader gpgErrorOutput = new BufferedReader(new InputStreamReader(gpgProcess.getErrorStream()));

        boolean executing = true;

        while(executing){
              try {
                int exitValue = gpgProcess.exitValue();

                if (gpgErrorOutput.ready()){
                    String error = getStreamText(gpgErrorOutput);
                    System.err.println(error);
                }else if (gpgOutput.ready()){
                    System.out.println(getStreamText(gpgOutput));

                }
            } catch (Exception e){
              //The process is not yet ready to exit.  Take a break and try again.
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e1) {
                    System.err.println("This thread has insomnia: " + e1.getMessage());
                }
            }
        }


    } catch (IOException e){
        e.printStackTrace();
    }

}

private String getStreamText(BufferedReader reader) throws IOException{
    StringBuilder result = new StringBuilder();
    try{
        while(reader.ready()){
            result.append(reader.readLine());
            if(reader.ready()){
                result.append("\n");
            }
        }
    }catch(IOException ioe){
        System.err.println("Error while reading the stream: " + ioe.getMessage());
        throw ioe;
    }
    return result.toString();
}

I've also tried ProcessBuilder instead of Runtime, but that's not the solution. Do you have any idea on how to solve this problem, or is it totally impossible to interact with the console during the key-generation process?

役に立ちましたか?

解決

gpg --genkey is an interactive call, which waits for input, which you never provide. Two possible solutions:

  1. Use bouncycastle instead, which is a native Java library for OpenPGP.
  2. As implementing an interactive GnuPG session will be rather complicated and error-prone, you might better use the "experimental feature" for batch key generation. From man gpg:

    --gen-key
          Generate a new key pair. This command is normally only used
          interactively.
    
          There is an experimental feature which allows you to create
          keys  in  batch  mode.  See  the  file `doc/DETAILS' in the
          source distribution on how to use this.
    

    The file doc/DETAILS is also available online. The section you want to look up is called "Unattended key generation". It's rather lengthy, so I didn't quote it here, but this is the example from the document on how to do it:

    $ cat >foo <<EOF
         %echo Generating a basic OpenPGP key
         Key-Type: DSA
         Key-Length: 1024
         Subkey-Type: ELG-E
         Subkey-Length: 1024
         Name-Real: Joe Tester
         Name-Comment: with stupid passphrase
         Name-Email: joe@foo.bar
         Expire-Date: 0
         Passphrase: abc
         %pubring foo.pub
         %secring foo.sec
         # Do a commit here, so that we can later print "done" :-)
         %commit
         %echo done
    EOF
    $ gpg --batch --gen-key foo
    
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top