gpt4 book ai didi

java - 通过运行时进程在 Java 中调用 GnuPG 来加密和解密文件 - 解密总是挂起

转载 作者:搜寻专家 更新时间:2023-10-31 19:58:32 25 4
gpt4 key购买 nike

注意:稍后再回来讨论这个问题,因为我一直找不到可行的解决方案。手动排空输入流而不是使用 BufferedReaders 似乎没有帮助,因为 inputStream.read() 方法会永久阻止程序。我将 gpg 调用放在批处理文件中,并从 Java 调用批处理文件只得到相同的结果。一旦使用 decrypt 选项调用 gpg,输入流似乎变得不可访问,从而阻塞了整个程序。当我有更多时间专注于任务时,我将不得不回到这里。与此同时,我必须通过其他方式(可能是 BouncyCaSTLe)进行解密。

可能尝试的最后一个选项是调用 cmd.exe,并通过该进程生成的输入流写入命令...

非常感谢您在此问题上提供的帮助。


我已经在这个问题上工作了几天,但没有取得任何进展,所以我想我应该向 exeprtise 寻求帮助。

我正在创建一个简单的程序,它将通过 Java 运行时进程调用 GnuPG。它需要能够加密和解密文件。加密有效,但我在解密文件时遇到了一些问题。每当我尝试解密文件时,进程都会挂起。exitValue() 总是抛出 IllegalThreadStateException 并且程序继续运行,就好像它仍在等待一样。这些方法的代码附在下面。该程序的最终目标是解密文件,并用 Java 解析文件内容。

我已经尝试了三种方法来使 gpgDecrypt 方法起作用。第一种方法涉及删除 passphrase-fd 选项并通过 catch block 中的 gpgOutput 流将密码写入 gpg,假设它像通过命令行一样提示输入密码。这没有用,所以我将密码放在一个文件中并添加了 -passphrase-fd 选项。在这种情况下,程序会无限重复。如果我通过 gpgOutput 流写入任何内容,程序就会完成。打印的 Exit 值将为 2,结果变量将为空。

第三个选项是 BouncyCaSTLe,但我在让它识别我的私钥时遇到了问题(这可能是一个单独的帖子)。

我用来加密和解密的 key 是 4096 位 RSA key ,由 GnuPG 生成。在使用密码和密码文件的这两种情况下,我都尝试通过 > myFile.txt 将输出传输到文件,但这似乎没有任何区别。

这里是 gpgEncrypt、gpgDecrypt 和 getStreamText 方法。我发布了两个,因为加密有效,我看不到我在执行和处理加密和解密方法之间的过程的方式之间有任何明显差异。 getStreamText 只是读取流的内容并返回一个字符串。

编辑:快速说明,Windows 环境。如果我复制解密命令输出,它可以通过控制台正常工作。所以我知道命令是有效的。


public 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;
}

public String gpgDecrypt(String file, String passphraseFile){
String result = null;
StringBuilder command = new StringBuilder("gpg --passphrase-fd 0 --decrypt \"");
command.append(file).append("\" 0<\"").append(passphraseFile).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);
}

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

最佳答案

我忘了你在 Java 中是如何处理它的,有 100 种方法。但是我被 decrypt 命令本身困住了,它非常有帮助,虽然你不需要所有这些引号,如果你想解密一个大文件,它是这样的:

gpg --passphrase-fd 0 --output yourfile.txt --decrypt /encryptedfile.txt.gpg/ 0</passwrdfile.txt

关于java - 通过运行时进程在 Java 中调用 GnuPG 来加密和解密文件 - 解密总是挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4367090/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com