encriptar desencriptar contraseña codigo cifrado archivos java encryption runtime.exec gnupg

contraseña - encriptar y desencriptar en java netbeans



Llamar a GnuPG en Java a través de un Runtime Process para cifrar y descifrar archivos: el descifrado siempre se cuelga (6)

¿Has intentado ejecutar ese comando desde la línea de comandos, no desde el código de Java? Puede haber un problema con la opción ''solo para tus ojos'', cuando GnuPG esperará la salida de la consola.

NOTA: Volviendo a esto más adelante ya que no he podido encontrar una solución funcional. Drenar las secuencias de entrada de forma manual en lugar de utilizar BufferedReaders no parece ser de ayuda ya que el método inputStream.read () bloquea permanentemente el programa. Puse la llamada gpg en un archivo por lotes y llamé al archivo por lotes de Java para obtener el mismo resultado. Una vez que se llama a gpg con la opción de descifrado, la secuencia de entrada parece ser inaccesible, bloqueando todo el programa. Tendré que volver a esto cuando tenga más tiempo para concentrarme en la tarea. Mientras tanto, tendré que hacer que el descifrado funcione por otros medios (probablemente BouncyCastle).

La última opción para intentar probablemente es llamar a cmd.exe y escribir el comando a través de la secuencia de entrada generada por ese proceso ...

Aprecio la asistencia en este tema.

He estado trabajando en este problema por un par de días y no he progresado, así que pensé en recurrir a la ayuda aquí para obtener ayuda.

Estoy creando un programa simple que llamará a GnuPG a través de un proceso de ejecución de Java. Necesita ser capaz de cifrar y descifrar archivos. El cifrado funciona, pero tengo algunos problemas para descifrar archivos. Cada vez que intento descifrar un archivo, el proceso se bloquea. exitValue() siempre lanza su IllegalThreadStateException y el programa repite como si aún estuviera esperando. El código para estos métodos se adjunta a continuación. El objetivo final del programa es descifrar el archivo y analizar sus contenidos en Java.

He intentado tres enfoques para hacer funcionar el método gpgDecrypt. El primer enfoque consistía en eliminar la opción contraseña-fd y escribir la frase de contraseña en gpg a través de la secuencia gpgOutput en el bloque catch, suponiendo que estaba solicitando la frase de contraseña como lo haría a través de la línea de comando. Esto no funcionó, así que puse la frase de contraseña en un archivo y agregué la opción -passphrase-fd. En este caso, el programa se repite infinitamente. Si escribo algo a través de la transmisión gpgOutput, el programa se completará. El valor de Salida impreso tendrá un valor de 2 y la variable de resultado estará en blanco.

La tercera opción es BouncyCastle, pero estoy teniendo problemas para que reconozca mi clave privada (que probablemente sea una publicación separada, todas juntas).

Las claves que estoy usando para cifrar y descifrar son claves RSA de 4096 bits, generadas por GnuPG. En ambos casos, utilizando la frase de contraseña y el archivo de frase de contraseña, intenté canalizar la salida a un archivo a través de > myFile.txt , pero no parece hacer ninguna diferencia.

Aquí están los métodos gpgEncrypt, gpgDecrypt y getStreamText. Publiqué ambos ya que el cifrado funciona, y no puedo ver diferencias evidentes entre cómo estoy ejecutando y manejo el proceso entre los métodos de encriptación y desencriptación. getStreamText solo lee los contenidos de las secuencias y devuelve una cadena.

EDITAR: nota rápida, entorno de Windows. Si copio la salida del comando de descifrado, funcionará perfectamente a través de la consola. Entonces sé que el comando es válido.

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


Este puede o no ser el problema (en la función de descifrado)

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

Usted está getInputStream el resultado de getInputStream dos veces. Obviamente gpgErrorOutput debería estar envolviendo el flujo de error, no el flujo de entrada.


Olvidé cómo lo manejas en Java, hay 100 métodos para eso. Pero me quedé atrapado con el comando de descifrado, fue muy útil, aunque no necesitabas todas las comillas y si deseas descifrar un archivo grande, dice así:

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


Me funcionó cuando reemplazo el comando de descifrado con el comando a continuación

gpg --output decrypted_file --batch --passphrase "passphrase goes here" --decrypt encrypted_file


int exitValue = gpgProcess.exitValue();

// da proceso no ha salido de la excepción


Hoy tropecé con este hilo porque estaba teniendo exactamente el mismo problema en cuanto a la ejecución del programa. El hilo de Cameron desde arriba contiene la solución, que es que debes drenar el inputStream de tu proceso. Si no lo haces, la transmisión se llena y se cuelga. Simplemente agregando

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

Antes de comprobar exitValue, lo solucionó por mí.