// он дает процессу не вышедшее исключение

 Возвращаясь к этому позже, так как я не смог найти рабочее решение. Удаление потоков ввода вручную вместо использования BufferedReaders, похоже, не помогает, так как метод inputStream.read () навсегда блокирует программу. Я поместил вызов gpg в пакетный файл и вызвал пакетный файл с Java, чтобы получить только тот же результат. Когда gpg вызывается с опцией decrypt, входной поток становится недоступным, блокируя всю программу. Я должен вернуться к этому, когда у меня будет больше времени, чтобы сосредоточиться на задаче. В то же время, мне придется заставить дешифровку работать другими способами (возможно, BouncyCastle).

Вероятно, последний вариант - вызвать cmd.exe и записать команду через поток ввода, сгенерированный этим процессом ...

Я ценю помощь в этом вопросе.

Я работал над этой проблемой в течение нескольких дней и не добился никакого прогресса, поэтому я решил обратиться за помощью к этой статье.

Я создаю простую программу, которая будет вызывать GnuPG через процесс выполнения Java. Он должен быть в состоянии зашифровать и расшифровать файлы. Шифрование работает, но у меня возникают проблемы с расшифровкой файлов. Всякий раз, когда я пытаюсь расшифровать файл, процесс зависает.exitValue() всегда выбрасывает исключение IllegalThreadStateException, и программа начинает пыхтеть, как будто все еще ждет. Код для этих методов прилагается ниже. Конечная цель программы - расшифровать файл и проанализировать его содержимое на Java.

Я попробовал три подхода к тому, чтобы заставить метод gpgDecrypt работать. Первый подход включал удаление опции passphrase-fd и запись парольной фразы в gpg через поток gpgOutput в блоке catch, предполагая, что он запрашивает парольную фразу, как это было бы через командную строку. Это не сработало, поэтому я поместил фразу-пароль в файл и добавил опцию -passphrase-fd. В этом случае программа повторяется бесконечно. Если я что-то напишу через поток gpgOutput, программа завершится. Напечатанное значение Exit будет иметь значение 2, а переменная результата будет пустой.

Третий вариант - BouncyCastle, но у меня возникают проблемы с распознаванием моего закрытого ключа (который, вероятно, является отдельным сообщением).

Ключи, которые я использую для шифрования и дешифрования, - это 4096-битные ключи RSA, сгенерированные GnuPG. В обоих случаях, используя парольную фразу и файл парольной фразы, я попытался передать вывод в файл через> myFile.txt, но это, похоже, не имеет никакого значения.

Вот методы gpgEncrypt, gpgDecrypt и getStreamText. Я написал оба, так как шифрование работает, и я не вижу никаких явных различий между тем, как я выполняю и обрабатываю процесс между методами шифрования и дешифрования. getStreamText просто читает содержимое потоков и возвращает строку.

РЕДАКТИРОВАТЬ: Быстрая заметка, среда Windows. Если я скопирую вывод команды decrypt, он отлично работает через консоль. Так что я знаю, что команда действительна.

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

Ответы на вопрос(6)

Ваш ответ на вопрос