Calling GnuPG in Java via a Runtime Process to encrypt and decrypt files - Decrypt always hangs

前端 未结 7 1453
隐瞒了意图╮
隐瞒了意图╮ 2021-01-18 16:25

NOTE: Coming back to this later as I\'ve been unable to find a working solution. Draining the input streams manually instead of using BufferedReaders doesn

相关标签:
7条回答
  • 2021-01-18 16:45

    I forget how you handle it in Java, there are 100 methods for that. But I was stuck with decrypt command itself, it was very helpful, though you didn't need all those quotes and if you wish to decrypt a large file, it goes like this:

    gpg --passphrase-fd 0 --output yourfile.txt --decrypt /encryptedfile.txt.gpg/ 0</passwrdfile.txt
    
    0 讨论(0)
  • 2021-01-18 16:46
    int exitValue = gpgProcess.exitValue();
    

    // it gives process has not exited exception

    0 讨论(0)
  • 2021-01-18 16:48

    It worked for me when i replace the decrypt command with below command

    gpg --output decrypted_file --batch --passphrase "passphrase goes here" --decrypt encrypted_file
    
    0 讨论(0)
  • 2021-01-18 16:49

    This may or may not be the problem (in the decrypt function)

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

    You are wrapping the result of getInputStream twice. Obviously gpgErrorOutput should be wrapping the error stream, not the input stream.

    0 讨论(0)
  • 2021-01-18 16:52

    Have you tried to run that command from command-line, not from Java code? There can be an issue with 'for your eyes only' option, when GnuPG will wait for console output.

    0 讨论(0)
  • 2021-01-18 16:53

    The following code works with GNUPG 2.1.X

    public static boolean gpgEncrypt(String file, String recipient,
            String outputFile) {
        boolean success = true;
        StringBuilder gpgCommand = new StringBuilder("gpg --recipient \"");
        gpgCommand.append(recipient).append("\" --output \"")
                .append(outputFile).append("\" --yes --encrypt \"");
        gpgCommand.append(file).append("\"");
    
        System.out.println("ENCRYPT COMMAND: " + gpgCommand);
        try {
            Process gpgProcess = Runtime.getRuntime().exec(
                    gpgCommand.toString());
    
            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);
                        success = false;
                        break;
                    } else if (gpgOutput.ready()) {
                        System.out.println(getStreamText(gpgOutput));
                    }
    
                    executing = false;
                } 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) {
            System.err.println("Error running GPG via runtime: "
                    + e.getMessage());
            success = false;
        }
    
        return success;
    }
    
    // gpg --pinentry-mode=loopback --passphrase "siv_test" -d -o
    // "sample_enc_data_op.txt" "sample_enc_data_input.gpg"
    
    public static String gpgDecrypt(String file, String passphrase,
            String outputfile) {
        String result = null;
        StringBuilder command = new StringBuilder(
                "gpg --pinentry-mode=loopback --passphrase \"");
        command.append(passphrase).append("\" -d -o \"").append(outputfile)
    
        .append("\" --yes \"").append(file)
    
        .append("\"");
        System.out.println("DECRYPT COMMAND: " + command.toString());
        try {
    
            Process gpgProcess = Runtime.getRuntime().exec(command.toString());
    
            BufferedReader gpgOutput = new BufferedReader(
                    new InputStreamReader(gpgProcess.getInputStream()));
            BufferedReader gpgErrorOutput = new BufferedReader(
                    new InputStreamReader(gpgProcess.getErrorStream()));
            BufferedWriter gpgInput = new BufferedWriter(
                    new OutputStreamWriter(gpgProcess.getOutputStream()));
    
            boolean executing = true;
    
            while (executing) {
                try {
                    if (gpgErrorOutput.ready()) {
                        result = getStreamText(gpgErrorOutput);
                        System.err.println(result);
                        break;
                    } else if (gpgOutput.ready()) {
                        result = getStreamText(gpgOutput);
                    }
                    String line = null;
                    while ((line = gpgOutput.readLine()) != null) {
                        System.out.println(line);
                    }
                    int exitValue = gpgProcess.exitValue();
                    System.out.println("EXIT: " + exitValue);
    
                    executing = false;
                } catch (IllegalThreadStateException e) {
                    System.out.println("Not yet ready.  Stream status: "
                            + gpgOutput.ready() + ", error: "
                            + gpgErrorOutput.ready());
    
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e1) {
                        System.err.println("This thread has insomnia: "
                                + e1.getMessage());
                    }
                }
            }
        } catch (IOException e) {
            System.err
                    .println("Unable to execute GPG decrypt command via command line: "
                            + e.getMessage());
        }
    
        return result;
    }
    
    private static 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();
    }
    
    0 讨论(0)
提交回复
热议问题