34

I want to decrypt a file using PGP keys.

I have downloaded PGP keys installer and installed. Using that I created a text file and encrypted the text file using PGP keys.

Then I got a .pgp extension file which is encrypted. Now I want to decrypt the same file using Java code using PGP.

In Java, How do I decrypt a text file which is already encrypted using PGP keys?

Ken Redler
  • 23,863
  • 8
  • 57
  • 69
user1216228
  • 383
  • 1
  • 4
  • 10
  • See also [Decrypt PGP encrypted file with passphrase only in Java](https://stackoverflow.com/questions/47715675/decrypt-pgp-encrypted-file-with-passphrase-only-in-java) – Vadzim Jul 24 '19 at 16:26

5 Answers5

12

You can write a simple wrapper around GNU PGP which basically executes the GPG command from Java.

The advantage of using GNU PGP is that you will not be tied to a specific library. The amount of documentation and support available online for third-party libraries is not as rich as other encryption schemes since most invoke PGP from command-line. The PGP keys will also stay in one common place i.e. the user specific key ring rather than exported in multiple files.

The GPG command for decryption is

echo "password" | gpg --passphrase-fd 0 --output plaintext.txt --decrypt encrypted.gpg

By specifying passphrase-fd as 0 you can provide the password through the standard input stream.

Here is how the Java code looks like -

public static void decryptFile(String privKeyPass) {
    String[] cmd = new String[];
    int i = 7;
    cmd[i++] = "gpg";
    cmd[i++] = "--passphrase-fd";
    cmd[i++] = "0";
    cmd[i++] = "--output";
    cmd[i++] = "plaintext.txt";
    cmd[i++] = "--decrypt";
    cmd[i++] = "encrypted.gpg";
    Process process = Runtime.getRuntime().exec(cmd);

    BufferedWriterout = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
    out.write(privKeyPass);
    try {
        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
   // Read process.getInputStream()
   // Read process.getErrorStream()
}
sunnyside
  • 121
  • 1
  • 3
8

I've written a complete code in Java with BounceCastle API and OpenPGP. In this source code you will find how to generate the key pair, encrypt and decrypt files. Take a look at: https://github.com/damico/OpenPgp-BounceCastle-Example

Damico
  • 1,107
  • 10
  • 5
  • that project worked for me after exporting the key file without ascii mask and "installing" the JCE lib. – 4F2E4A2E Jun 23 '14 at 11:56
8

Try do see this topic. I have just taken a brief look at it, but I think it is what you need. http://sloanseaman.com/wordpress/2012/05/13/revisited-pgp-encryptiondecryption-in-java/

George Hawkins
  • 37,044
  • 7
  • 30
  • 43
MikhailSP
  • 3,233
  • 1
  • 19
  • 29
  • 5
    Like most of the other answers here, the linked to blog entry uses the [Bouncy Castle Java packages](https://www.bouncycastle.org/java.html). The Bouncy Castle code base itself includes a lot of [PGP examples](https://github.com/bcgit/bc-java/tree/master/pg/src/main/java/org/bouncycastle/openpgp/examples). If you want to see these examples separated out into a standalone project with the Bouncy Caste dependencies pulled in by Maven then see [openpgp-bc-examples](https://github.com/george-hawkins/openpgp-bc-examples). – George Hawkins Jun 21 '16 at 11:54
4

BouncyCastle has certain support for OpenPGP ("certain" because they mention only RFC 2440 and not RFC 4880 which is more recent). Also you can take a look at OpenPGPBlackbox package of our SecureBlackbox (Java edition), which provides complete support for OpenPGP including LDAP access to keys and other advanced functions.

Christian
  • 1,258
  • 10
  • 11
Eugene Mayevski 'Callback
  • 45,135
  • 8
  • 71
  • 121
1

Try to take a look to JCA CryptoSpec. I am not sure about PGP, but I think you can find there a Provider for your purpose.

As far as I remember code should be something like:

// get cipher object for password-based encryption
Cipher cipher1 = Cipher.getInstance("PBEWithMD5AndDES");//You have to pass here algorithm name which PGP uses. May be you have to find and init provider for it.

// initialize cipher for decryption, using one of the 
// init() methods that takes an AlgorithmParameters 
// object, and pass it the algParams object from above
cipher1.init(Cipher.DECRYPT_MODE, myKey, algParams);


FileInputStream fis;
FileOutputStream fos;
CipherInputStream cis;

fis = new FileInputStream("/tmp/a.txt");
cis = new CipherInputStream(fis, cipher1);
fos = new FileOutputStream("/tmp/b.txt");
byte[] b = new byte[8];
int i = cis.read(b);
while (i != -1) {
    fos.write(b, 0, i);
    i = cis.read(b);
}
fos.close();
MikhailSP
  • 3,233
  • 1
  • 19
  • 29