Decryption of pgp data using Java

We can decrypt an OpenPGP encrypted file if it is encrypted with a public key and we have the corresponding private key, or if it was encrypted with a password (also known as conventional encrypted or PBE).

Below you will find examples that demonstrate in practice how to decrypt with DidiSoft OpenPGP Library for Java. In earlier OpenPGP implementations only one file was contained into a single OpenPGP archive. Newer implementations can encrypt multiple files and folders in one file.

Decrypt encrypted file

1. With private key located in a file
2. With private key located in a KeyStore

Decrypt encrypted Stream

3. With private key located in a stream
4. With private key located in a KeyStore

Decrypt encrypted String

5. With private key located in a file
6. With private key located in a KeyStore 

Decrypt OpenPGP encrypted file that contains multiple files

7. With private key located in a file
8. With private key located in a KeyStore

Decrypt password encrypted (PBE) OpenPGP archive

9. Decrypt PBE OpenPGP archive

Appendix A
Exception handling

1. Decrypt file with private key located in a file

This example demonstrates OpenPGP file decryption with a private key stored in a file. The private key password is also needed, in order the key to be used.

The last parameter is the location where we want the decrypted file to be stored. The DecryptFile method returns a String that represent the original file name of the content that was encrypted, which we can use lately to rename OUTPUT.txt with.

import com.didisoft.pgp.PGPLib;
 
public class DecryptFile {
 public static void main(String[] args) throws Exception{
   // initialize the library instance
   PGPLib pgp = new PGPLib();
 
   String privateKeyFile = "private.key";
   String privateKeyPass = "changeit";
 
   // The decrypt method returns the original name of the file
   // that was encrypted. We can use it afterwards,
   // to rename OUTPUT.txt.
   String originalFileName = pgp.decryptFile("encrypted.pgp",
					privateKeyFile,
					privateKeyPass,
					"OUTPUT.txt");
 }
}

2. Decrypt file with private key located in a KeyStore

This example shows how to decrypt a file with private key stored in a Key store. Keeping our private keys in a KeyStore gives us extra layer of security.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
 
import com.didisoft.pgp.KeyStore;
import com.didisoft.pgp.PGPLib;
 
public class KeystoreDecryptFile {
  public static void main(String[] args) throws Exception {
    // initialize the KeyStore instance
    KeyStore keyStore = new KeyStore("pgp.keystore", "changeit");
 
    // initialize the library instance
    PGPLib pgp = new PGPLib();
 
    // The decrypt method returns the original name of the file
    // that was encrypted. We can use it afterwards,
    // to rename OUTPUT.txt.
    String originalFileName = pgp.decryptFile("encrypted.pgp",
						keyStore,
						"changeit",
						"OUTPUT.txt");
  }
}

3. Decrypt stream with private key located in a stream

Sometimes we may receive an encrypted data in a way suitable to be read as an input stream, in that case it is easier to decrypt it directly instead of writing it to a file before that. The example below shows how to achieve this:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
 
import com.didisoft.pgp.PGPLib;
 
public class DecryptStream {
 
 public static void main(String[] args) throws Exception{
   // create instance of the library
   PGPLib pgp = new PGPLib();
 
  // obtain an encrypted data stream
  InputStream encryptedStream = new FileInputStream("encrypted.pgp");
 
  InputStream privateKeyStream = new FileInputStream("private.key");
  String privateKeyPassword = "changeit";
 
  // specify the destination stream of the decrypted data
  OutputStream decryptedStream = new FileOutputStream("OUTPUT.txt");
 
  pgp.decryptStream(encryptedStream,
  	            privateKeyStream,
        	    privateKeyPassword,
        	    decryptedStream);
 }
}

4. Decrypt stream with private key located in a KeyStore

This example shows how to decrypt an OpenPGP encrypted stream when our private decryption key is stored in a KeyStore object.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
 
import com.didisoft.pgp.KeyStore;
import com.didisoft.pgp.PGPLib;
 
public class KeyStoreDecryptStream {
 public static void main(String[] args) throws Exception {
   // initialize the KeyStore instance
   KeyStore keyStore = new KeyStore("pgp.keystore", "changeit");
 
   // initialize the library instance
   PGPLib pgp = new PGPLib();
 
   // obtain the encrypted stream
   InputStream encryptedStream = new FileInputStream("encrypted.pgp");
   // specify the decrypted output stream
   OutputStream decryptedStream = new FileOutputStream("OUTPUT.txt");
 
   String decryptionKeyPassword = "changeit";
 
   pgp.decryptStream(encryptedStream,
			  keyStore,
			  decryptionKeyPassword,
			  decryptedStream);
 }
}

5. Decrypt encrypted String

With the help of the library we can easily decrypt an OpenPGP encrypted message available as String:

import java.io.*;
import com.didisoft.pgp.*;
 
public class DecryptStringDemo {
    public static void main(String[] args) throws Exception {
        // create an instance of the library
        PGPLib pgp = new PGPLib();
 
        String openpgpMessage = "..."; // Fill here the OpenPGP encrypted message
 
        String privateKeyFile = "c:\\my_private_key.asc";
        String privateKeyPassword = "my passsword";
 		InputStream privateKeyStream = null;
 
        try {
        	privateKeyStream = new FileInputStream(privateKeyFileName);
        	String decryptedMessage = pgp.decryptString(openpgpMessage,
                                                    	privateKeyFile,
                                                    	privateKeyPassword);
        } finally {
        	if (privateKeyStream != null)
        		privateKeyStream.close();
        }
 
        System.out.println("plain message: " + decryptedMessage);
    }
}

7. Decrypt encrypted String

Similar to the example above we can decrypt a String message when our private key is located in a KeyStore object.

import java.io.*;
import com.didisoft.pgp.*;
 
public class DecryptStringDemo {
    public static void main(String[] args) throws Exception {
        // create an instance of the library
        PGPLib pgp = new PGPLib();
 
        String openpgpMessage = "..."; // Fill here the OpenPGP encrypted message
 
        String privateKeyPassword = "my passsword";
 		 KeyStore keyStore = KeyStore.OpenFile("mylocal.keystore", "my password");
 
        String decryptedMessage = pgp.decryptString(openpgpMessage,
                                                    	keyStore,
                                                    	privateKeyPassword);
 
        System.out.println("plain message: " + decryptedMessage);
    }
}

7. Decrypt OpenPGP encrypted file to a folder

This practical illustration shows how to decrypt an OpenPGP archive containing multiple files and/or folders. Of course it can be used for classic OpenPGP files too. The decryptFileTo method returns array with absolute paths to the decrypted files.

import com.didisoft.pgp.*;
 
public class DecryptFileTo {
 public static void main(String[] args) throws Exception{
  // initialize the library instance
  PGPLib pgp = new PGPLib();
 
  String privateKeyFile = "private.key";
  String privateKeyPass = "changeit";
 
  // The decrypt method returns array with decrypted file paths
  String[] files = pgp.decryptFileTo("encrypted.pgp",
				  privateKeyFile,
				  privateKeyPass,
				  "c:\\Temp\\");
 
  for (int i=0; i < files.length; i++) {
    System.out.println("File " + String.valueOf(i) + " decrypted to: " + files[i]);
  }
 }
}

 8. Decrypt OpenPGP archive to a folder with private key in a KeyStore

This example is equivalent to the above one, except that the private decryption key is stored in a KeySrore object.

import com.didisoft.pgp.*;
 
public class DecryptFileTo {
 public static void main(String[] args) throws Exception{
  // initialize the library instance
  PGPLib pgp = new PGPLib();
 
  KeyStore keyStore = new KeyStore("my.keystore", "keystore pasword");
  String privateKeyPass = "changeit";
 
  // The decrypt method returns array with decrypted file paths
  String[] files = pgp.decryptFileTo("encrypted.pgp",
				   keyStore,
				   privateKeyPass,
				   "c:\\Temp\\");
 
  for (int i=0; i < files.length; i++) {
   System.out.println("File " + String.valueOf(i) + " decrypted to: " + files[i]);
  }
 }
}

 9. Decrypt password encrypted OpenPGP file

In order to decrypt a conventional encrypted OpenPGP archive we have to use the same password used for encryption. Below is an example demonstrating how to decrypt such file in Java.

import com.didisoft.pgp.*;
 
public class DecryptFilePBE {
 public static void main(String[] args) throws Exception{
   // initialize the library instance
   PGPLib pgp = new PGPLib();
 
   // The decrypt method returns the original name of the file
   // that was encrypted. We can use it afterwards,
   // to rename OUTPUT.txt
   String originalFileName = pgp.decryptFile("encrypted.pgp",
                                             "decryption password",
                                             "OUTPUT.txt");
 }
}

Exception handling

The quick exception handling solution for the decryption methods is to catch only com.didisoft.pgp.PGPException.

However we can also catch a number of PGPException sub classes that can reveal further the cause of the error condition. In that case PGPException must be caught last.

import java.io.IOException;
import com.didisoft.pgp.*;
import com.didisoft.pgp.exceptions.*;
 
public class ExceptionHandlingDemo {
 public static void main(String[] a) {
   PGPLib pgp = new PGPLib();
   try {
    pgp.decrypt...
   } catch (IOException e) {
    // error reading input or writing output
   } catch (NonPGPDataException e) {
    // the passed encrypted input is not a valid OpenPGP archive
   } catch (IntegrityCheckException e) {
    // the passed encrypted input is corrupted
   } catch (FileIsPBEEncryptedException e) {
    // the passed encrypted input is encrypted with a password,
    // but we try to decrypt it with a private key
   } catch (NoPrivateKeyFoundException e) {
    // if the supplied private key source does not contain a private key 
    // or is corrupted
   } catch (WrongPrivateKeyException e) {
    // the encrypted input was encrypted with a different private key
    // than the provided one
   } catch (WrongPasswordException e) {
    // the password for the provided private key is wrong
   } catch (DetachedSignatureException e) {
    // the input is not an encrypted message, but a detached OpenPGP signature
   } catch (PGPException e) {
    // general decryption error not among the above ones 
   }
 
 }
}

Summary

In this chapter we have discussed OpenPGP decryption with DidiSoft OpenPGP Library for Java.