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
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
int exitValue = gpgProcess.exitValue();
// it gives process has not exited exception
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
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.
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.
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();
}