Volání GnuPG v Javě pomocí Runtime proces k šifrování a dešifrování souborů - dešifrování vždy zablokuje

hlasů
5

Poznámka: Vrátíme-li se později, jak jsem nebyl schopen najít funkční řešení. Odvodnění vstupní toky ručně namísto s použitím BufferedReaders nezdá pomoci jako metoda inputStream.read () trvale blokuje programu. Položil jsem gpg volání v dávkovém souboru, a nazval dávkový soubor z Javy získat pouze stejný výsledek. Jakmile je gpg volal s možností dešifrovat vstupní proud Zdá se stanou nedostupnými, blokuje celý program. Budu se muset vrátit k tomu, až budu mít více času soustředit se na daný úkol. Do té doby budu muset dostat dešifrovací práci jiným způsobem (asi BouncyCastle).

Poslední možnost se pravděpodobně snažit je zavolat cmd.exe a napsat příkaz prostřednictvím vstupního proudu vytvořených tímto způsobem ...

Oceňuji pomoc v této záležitosti.


Pracoval jsem na tento problém za pár dní a neučinil žádný pokrok, a tak jsem myslel, že se obrátit na exeprtise zde o nějakou pomoc.

Jsem vytvořit jednoduchý program, který bude volat GnuPG přes proces runtime Java. To musí být schopen k šifrování a dešifrování souborů. Šifrování funguje, ale mám nějaké problémy dešifrování souborů. Kdykoliv se snažím dešifrovat soubor, proces zablokuje. exitValue()Vždy hází to IllegalThreadStateException a program chugs spolu, jako kdyby se to ještě čeká. Kód pro tyto metody je připojen níže. Hlavním cílem tohoto programu je soubor dešifrovat a analyzovat jeho obsah v Javě.

Zkoušel jsem tři přístupy k získání metodu gpgDecrypt pracovat. První přístup podílí odstraníme možnost heslo-fd a psaní přístupové heslo k gpg pomocí proudu gpgOutput v bloku catch, za předpokladu, že byla výzva k zadání přístupového hesla, jako by to přes příkazový řádek. To nefungovalo, tak jsem dal přístupové heslo do souboru a přidána možnost -passphrase-fd. V tomto případě program opakuje do nekonečna. Pokud napíšu něco přes gpgOutput vysílat program dokončí. Hodnota Exit vytištěna bude mít hodnotu 2, a proměnná výsledkem bude prázdná.

Třetí možností je BouncyCastle, ale mám problémy se ho uznat svůj soukromý klíč (což je pravděpodobně samostatný příspěvek dohromady).

Klíče Já používám k šifrování a dešifrování jsou 4096-bit RSA klíče, generovaných GnuPG. V obou případech za použití přístupové heslo a soubor přístupového hesla, jsem se snažil potrubí výstup do souboru pomocí > myFile.txt, ale nezdá se, že žádný rozdíl.

Zde jsou způsoby gpgEncrypt, gpgDecrypt a getStreamText. I vysláni oba od šifrovat prací, a já nevidím žádné do očí bijící rozdíly mezi tím, jak jsem provádění a manipulaci proces mezi šifrování a dešifrování metody. getStreamText právě čte obsah potoků a vrátí řetězec.

EDIT: Rychlá poznámka, prostředí Windows. Mám-li zkopírovat příkaz decrypt výstup, funguje přes konzoli v pohodě. Takže vím, že je příkaz platný.


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();
}
Položena 06/12/2010 v 14:57
zdroj uživatelem
V jiných jazycích...                            


6 odpovědí

hlasů
3

Zapomněla jsem, jak se s ní zacházet v Javě, existuje 100 metody pro to. Ale já jsem se zasekl s dešifrovacím velení sám, to bylo velmi užitečné, když jste nemuseli všechny ty uvozovky a pokud chcete dešifrovat velký soubor, to vypadá takto:

gpg --passphrase-fd 0 --output yourfile.txt --decrypt /encryptedfile.txt.gpg/ 0</passwrdfile.txt
Odpovězeno 27/10/2011 v 17:05
zdroj uživatelem

hlasů
1

jsem narazil na toto vlákno dnes, protože jsem měl přesně stejný problém, pokud jde o programové zavěšení. Cameron nit seshora obsahuje řešení, které je, že musíte být vypouštění InputStream ze svého procesu. Pokud tak neučiníte, proud zaplní a zablokuje. pouhým přidáním

String line = null;
while ( (line = gpgOutput.readLine()) != null ) {
     System.out.println(line);
}

Před kontrolou ji exitValue stanovené pro mě.

Odpovězeno 21/02/2013 v 15:08
zdroj uživatelem

hlasů
1

To může, ale nemusí být problém (ve funkci dešifrovacím)

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

Ty jsou balení výsledek getInputStreamdvakrát. Zřejmě gpgErrorOutputje třeba balení chybovou proud, nikoliv vstupního proudu.

Odpovězeno 06/12/2010 v 15:01
zdroj uživatelem

hlasů
1

Už jste se snažil běžet tento příkaz z příkazového řádku, nikoli z kódu v jazyce Java? Tam může být problém s ‚jen pro vaše oči‘ volba, kdy bude GnuPG čekat na výstup konzoly.

Odpovězeno 06/12/2010 v 15:00
zdroj uživatelem

hlasů
0

Fungovalo to pro mě, když jsem nahradit příkaz dešifrovacího se pod velením

gpg --output decrypted_file --batch --passphrase "passphrase goes here" --decrypt encrypted_file
Odpovězeno 29/12/2010 v 10:58
zdroj uživatelem

hlasů
0
int exitValue = gpgProcess.exitValue();

// dává proces nebyl ukončen výjimku

Odpovězeno 28/12/2010 v 14:09
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more