如何调用CMD从Java创建GnuPG-Keypair

时间:2014-03-06 09:22:45

标签: java console runtime processbuilder gnupg

我正在尝试用Java执行gpg命令来创建一个新的Keypair,但是我没有从控制台得到答案。如果我尝试为版本gpg --version执行gpg-command或使用gpg --list-key检索密钥列表,我的代码就可以正常运行。

我正在使用其他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();
}

我也尝试过ProcessBuilder而不是Runtime,但这不是解决方案。 您对如何解决此问题有任何想法,或者在密钥生成过程中是否完全无法与控制台进行交互?

1 个答案:

答案 0 :(得分:1)

gpg --genkey是一个交互式调用,等待您从未提供的输入。两种可能的解决方案:

  1. 使用bouncycastle代替,这是OpenPGP的本机Java库。
  2. 由于实现交互式GnuPG会话会相当复杂且容易出错,因此您最好使用“实验性功能”来生成批量密钥。来自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.
    

    文件doc/DETAILS is also available online。要查找的部分称为“无人值守密钥生成”。这是相当冗长的,所以我没有在这里引用它,但这是文件中关于如何做到这一点的例子:

    $ 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