Utiliser GnuPG avec Java
Je n'ai pas suivi l'évolution de GnuPG, je connais ça depuis un moment, mais je sais pas quel est son positionnement au niveau professionnel. Ce que je sais c'est qu'il s'est imposé de-facto dans un projet dans une banque ... Je me suis dit que c'était la première fois qu'il ne fallait pas batailler pour utiliser de l'open source :)
Donc voila des renseignements sur GnuPG si vous en voulez ...
Sinon j'ai un peu dû modifier cette classe pour qu'il accepte qu'on écrive dans stdin lors de l'appel d'une fonction système :
public static String[] exec(String cmd, boolean throwExceptions) throws HelperException { return execAndWrite(cmd, null, throwExceptions); } public static String[] execAndWrite(String cmd, String write) { try { return execAndWrite(cmd, write, false); } catch (HelperException e) { log.error(e,e); } return new String[0]; } public static String[] execAndWrite(String cmd, String write, boolean throwExceptions) throws HelperException { try { log.trace("$ " + cmd); Process proc = Runtime.getRuntime().exec(cmd); if (write != null) { BufferedWriter out = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())); log.trace("! " + write); out.write(write); out.close(); } /*- et après c'est pareil ... -*/
Voila une fois cette modif faite on peut partir sur un nouveau helper qui dans un premier temps va simplement nous aider a encrypter décrypter ... je vous laisse le soin de le modifier/l'étendre pour qu'il fasse le reste, si j'en ai besoin je le ferai et j'ajournerai :p (Sinon hésitez pas a commenter !)
Dans un premier temps définissons 3 variables :
public class GnuPGHelper { private static String gnupgCommand = null; private static String gnupgOptions = " --batch "; private static boolean ascii = false; }
A quoi pourrait bien ressemble un appel system GnuPG ?
private static File gnupgCommand(String commandArgs, File inputFile, File outputFile, String passPhrase) throws HelperException { /*- On récupère le path de la fonction -*/ if (gnupgCommand == null) { String which = ProcessHelper.exec("which gpg", true)[0]; if ((which == null) || (which.trim().equals("")) || which.startsWith("no gpg")) { throw new HelperException("GPG not correctly installed !"); } gnupgCommand = which; } try { /*- On s'assure que le fichier n'existe pas déja, ça génèrerai une exception ! -*/ if (outputFile.exists()) { outputFile.delete(); } /*- Voici la fonction qu'on va appeler -*/ String fullCommand = gnupgCommand + " " + gnupgOptions + " --output " + outputFile.getAbsolutePath() + " " + commandArgs + " " + inputFile.getAbsolutePath(); ProcessHelper.execAndWrite(fullCommand, passPhrase, true); } catch (Exception e) { throw new HelperException(e); } return outputFile; }
On travaille sur des fichiers, c'est plus simple pour les fichier compressé puisque le buffer ne sera pas assez long pour le lire, et on aura des soucis pour le réécrire ... Bref ... C'est plus simple comme ça !
Ensuite nos fonction pour encrypter décrypter :
public static File encrypt(File inputFile, String keyID) throws HelperException { File outputFile = new File(inputFile.getAbsolutePath() + ".gpg"); return gnupgCommand(" -r " + keyID + (ascii ? " --armor " : "") + " --encrypt", inputFile, outputFile, null); } public static File decrypt(File inputFile, String passPhrase) throws HelperException { File ret = null; try { ret = gnupgCommand(" --logger-fd 1 --passphrase-fd 0 --decrypt ", inputFile, File.createTempFile("GnuPG_", ".tmp"), passPhrase); } catch (Exception e) { throw new HelperException(e); } if ((ret == null) || !ret.exists()) { throw new HelperException("Decrypt failed ! (Check your passphrase first...)"); } return ret; }
Voila rien de plus simple une fois qu'on connait comment GPG fonctionne ...
Ensuite une dernière fonction pour la forme :
public static void setAsciiEncryption(boolean check) { GnuPGHelper.ascii = check; }
Et on est partit pour les tests :
public static void main(String args[]) { GnuPGHelper.setAsciiEncryption(true); File encryptedFile = null; try { log.debug("------------------"); log.debug("Testing encryption"); /*- create a new file to crypt -*/ File inputFile = new File("/tmp/TestGnuPGInput.txt"); FileHelper.createContent(inputFile, new StringBuffer("Write what \n\t you want here to test !")); /*- encrypt this file -*/ encryptedFile = GnuPGHelper.encrypt(inputFile, "myKeyId"); /*- display the content of the file -*/ log.info(FileHelper.getFileContentsAsString(encryptedFile.toURL())); log.debug("---------------"); log.debug("Testing decrypt"); /*- decrypt the file -*/ File decryptedFile = GnuPGHelper.decrypt(encryptedFile, "myPassPhrase"); log.info(FileHelper.getFileContentsAsString(decryptedFile.toURL())); } catch (Exception e) { log.error(e,e); } }
Vous pouvez tester avec et sans le AsciiEncryption ! En tout cas ici ça foncitonne :)

Comments
Tu parles que GnuPG s'est imposé dans une banque... sais-tu laquelle ?
merci d'avance !
merci pour ce super site qui nous donne des informations utiles et qui nous évite de les chercher partout ailleur ;)