Encryption is the most widely used function of the OpenPGP cryptography. In order to encrypt a file we need the public key of the recipient(s). Another option is to conventionally encrypt only with a password.
The first OpenPGP implementations, starting with the original PGP 2.x, used to encrypt only one data file into a single encrypted file. Newer implementations can store multiple files and folders into a single encrypted file.
With OpenPGP Library for Java we have two options. The first one is to keep the recipient’s public key in a file on the disk. The second option is to store it in a KeyStore object.
Encrypt a file
1. With recipient’s public key located in a file
2. With recipient’s public key located in a KeyStore
Encrypt a Stream
3. With recipient’s public key located in a stream
4. With recipient’s public key located in a KeyStore
Encrypt a String
5. With recipient’s public key located in a file
6. With recipient’s public key located in a KeyStore
Encrypt multiple files
7. With recipient’s public key located in a file(s)
8. With recipient’s public key located in a KeyStore
Appendix: Exception handling
1. Encrypt file with recipient’s public key located in a file
This example shows how to encrypt a data file, having the recipient’s public key in a file. In our case the recipient’s public key file has extension .key, but it can be anything else. The most common public key file name extensions are: *.asc, *.pgp, *.pgpkey.
import com.didisoft.pgp.PGPLib; public class EncryptFile { public static void main(String[] args) throws Exception{ // create an instance of the library PGPLib pgp = new PGPLib(); // is output ASCII or binary boolean asciiArmor = false; // should integrity check information be added // set to true for compatibility with GnuPG 2.2.8+ boolean withIntegrityCheck = true; pgp.encryptFile("INPUT.txt", "public.key", "OUTPUT.pgp", asciiArmor, withIntegrityCheck); } } |
All encrypt methods have two additional parameters:
asciiArmor specifies the format of the result file, when true the file is in ASCII armored format suitable for Email attachments, when false the output file is in binary format.
When withIntegrityCheck is true additional integrity check information is appended to the encrypted file. Set to false for compatibility with older versions of PGP such as 6.5.8.
2. Encrypt file with recipient’s public key located in a KeyStore
We should choose to store our OpenPGP keys in a KeyStore object when we need additional layer of security. This example shows how to encrypt a file with public key located in a key store. ( Note that a key with UserId demo@didisoft.com should already be imported in the KeyStore file.)
import com.didisoft.pgp.KeyStore; import com.didisoft.pgp.PGPLib; public class KeystoreEncryptFile { public static void main(String[] args) throws Exception{ // create an instance of the KeyStore KeyStore keyStore = new KeyStore("pgp.keystore", "changeit"); // create an instance of the library PGPLib pgp = new PGPLib(); String recipientUserId = "demo@didisoft.com"; // is output ASCII or binary boolean asciiArmor = true; // should integrity check information be added // set to true for compatibility with GnuPG 2.2.8+ boolean withIntegrityCheck = true; pgp.encryptFile("INPUT.txt", keyStore, recipientUserId, "encrypted.pgp", asciiArmor, withIntegrityCheck); } } |
3. Encrypt stream with recipient’s public key located in a file
This example shows how to encrypt a stream. This way we can encrypt not only files but any other source that can be read as a stream.
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import com.didisoft.pgp.PGPLib; public class EncryptStream { public static void main(String[] args) throws Exception{ // create an instance of the library PGPLib pgp = new PGPLib(); // is output ASCII or binary boolean asciiArmor = true; // should integrity check information be added // set to true for compatibility with GnuPG 2.2.8+ boolean withIntegrityCheck = true; // obtain the streams InputStream inStream = new FileInputStream("INPUT.txt"); InputStream keyStream = new FileInputStream("public.key"); OutputStream outStream = new FileOutputStream("encrypted.pgp"); // Here "INPUT.txt" is just a string to be written in the // OpenPGP packet which contains: // file name string, timestamp, and the actual data bytes pgp.encryptStream(inStream, "INPUT.txt", keyStream, outStream, asciiArmor, withIntegrityCheck); } } |
4. Encrypt stream with recipient’s public key located in a KeyStore
In this example the message source and the encrypted output are streams too. The public key of the recipient is located in a KeyStore file.
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 KeyStoreEncryptStream { public static void main(String[] args) throws Exception{ // create an instance of the KeyStore KeyStore keyStore = new KeyStore("pgp.keystore", "changeit"); String recipientUserId = "demo@didisoft.com"; // create an instance of the library PGPLib pgp = new PGPLib(); // is output ASCII or binary boolean asciiArmor = true; // should integrity check information be added // set to true for compatibility with GnuPG 2.2.8+ boolean withIntegrityCheck = true; // obtain the streams InputStream inStream = new FileInputStream("INPUT.txt"); OutputStream outStream = new FileOutputStream("encrypted.pgp"); // Here "INPUT.txt" is just a string to be written in the // OpenPGP data packet which contains: // file name string, timestamp, and the actual data bytes pgp.encryptStream(inStream, "INPUT.txt", keyStore, recipientUserId, outStream, asciiArmor, withIntegrityCheck); } } |
5. Encrypt a String message
With the help of the library we can easily encrypt a String message:
import com.didisoft.pgp.PGPLib; public class EncryptStringDemo { public static void main(String[] args) throws Exception { String stringToEncrypt = "the quick brown fox jumps"; // create an instance of the library PGPLib pgp = new PGPLib(); String publicEncryptionKeyFile = "c:\\recipient_public_key.asc"; InputStream publicEncryptionKeyStream = null; try { publicEncryptionKeyStream = new FileInputStream(publicKeyFileName); // encrypt String encryptedString = pgp.encryptString(stringToEncrypt, publicEncryptionKeyStream); } finally { if (publicEncryptionKeyStream != null) publicEncryptionKeyStream.close(); } } } |
6. Encrypt a String message with recipient’s public key located in a KeyStore
This example is similar to the above one but now the recipient’s public key is located in a KeyStore.
import com.didisoft.pgp.PGPLib; public class EncryptStringDemo { public static void main(String[] args) throws Exception { String stringToEncrypt = "the quick brown fox jumps"; // create an instance of the library PGPLib pgp = new PGPLib(); KeyStore keystore = KeyStore.openFile("c:\\mylocal.keystore", "my password"); // encrypt String encryptedString = pgp.encryptString(stringToEncrypt, keystore, keystore.getKeyIdForKeyIdHex("A0324F1D")); } } |
7. Encrypt multiple files with public key(s) located in file(s)
Encryption of multiple files and folders is supported by the newer OpenPGP implementations (like PGP Desktop 9+) so if you plan to use this feature, please ensure that your recipients are using compatible OpenPGP software.
(This feature is available as of version 2.5.5)
import com.didisoft.pgp.*; public class EncryptFilesDemo { public static void main(String[] args) throws Exception{ // create an instance of the library PGPLib pgp = new PGPLib(); // if true the output file will be in ASCII armored format, // otherwise will be in binary format boolean asciiArmor = true; // when true, additional integrity check information is added boolean withIntegrityCheck = true; // multiple files to be encrypted in one OpenPGP archive String[] inputFiles = {"INPUT1.txt", "INPUT2.txt", "INPUT3.txt"}; // for each recipient specify the location of her public key file String[] recipientsPublicKeys = {"public_key1.asc", "public_key2.asc", "public_key3.asc"}; pgp.encryptFiles(inputFiles, recipientsPublicKeys, "encrypted.pgp", asciiArmor, withIntegrityCheck); } } |
8. Encrypt multiple files with public key(s) located in a KeyStore
This example is equivalent to example (5) except that the recipients’ keys are first imported in a KeyStore object.
import com.didisoft.pgp.*; public class EncryptFilesDemo { public static void main(String[] args) throws Exception{ // create an instance of the library PGPLib pgp = new PGPLib(); // if true the output file will be in ASCII armored format, // otherwise will be in binary format boolean asciiArmor = true; // when true, additional integrity check information is added boolean withIntegrityCheck = true; String[] inputFiles = {"INPUT1.txt", "INPUT2.txt", "INPUT3.txt"}; // KeyStore file containing the recipients' public keys KeyStore keyStore = new KeyStore("mykeys.keystore", "password"); // recipients' specified with User Id (Key Id can be used as well) String[] recipientsUserIds = {"recipient1@company.com", "John Doe", "Clearing House"}; pgp.encryptFiles(inputFiles, keyStore, recipientsUserIds, "encrypted.pgp", asciiArmor, withIntegrityCheck); } } |
Exception handling
All encrypt methods throw com.didisoft.pgp.PGPException.
We can catch a few sub classes of PGPException that reside in package com.didisoft.pgp.exceptions, in order to identify specific error issues. In that case PGPException must be caught last.
Below is a part of an example code that illustrates the various exception sub classes that we can expect from the encrypt methods:
import java.io.*; import com.didisoft.pgp.*; import com.didisoft.pgp.exceptions.*; public class ExceptionDemo { public static void main(String[] a) { PGPLib pgp = new PGPLib(); try { pgp.encrypt... } catch (IOException e) { // in case of I/O error } catch (NoPublicKeyFoundException e) { // the supplied public key source does not contain a public key } catch (KeyIsExpiredException e) { // the supplied public key is expired } catch (KeyIsRevokedException e) { // the supplied public key is revoked } catch (PGPException e) { // general OpenPGP encryption error } } } |
For general information on the available exceptions that sub class com.didisoft.pgp.PGPException, please refer to the exception handling section.
Summary
In this chapter we have shown how to OpenPGP encrypt files and streams. Below is a list of the methods used in the examples:
PGPLib.encryptFile | OpenPGP encrypts a file |
PGPLib.encryptFiles | OpenPGP encrypts multiple files into a single archive |
PGPLib.encryptStream | OpenPGP encrypts a stream |
PGPLib.encryptString | OpenPGP encrypts a String |
From here you can continue to the examples that demonstrate OpenPGP decryption or to the examples’ table of contents.