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
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();
}