This example demonstrates how to decrypt a file that has been OpenPGP signed and encrypted in one pass. We can still decrypt it with the standard decrypt method, but with decrypt and verify in one pass we can also verify that the sender of the message is the one that we expect.
In order to run the decrypt and verify method we need our private key (to decrypt the message) and the public key of the sender (to verify the digital signature).
1) Decrypt and verify file with keys located in files on the disk
Note that even if the signature is invalid the contained file will be extracted.
import com.didisoft.pgp.PGPLib;
public class DecryptAndVerify {
public static void main(String[] args) throws Exception{
// create an instance of the library
PGPLib pgp = new PGPLib();
boolean validSignature =
pgp.decryptAndVerifyFile("encrypted.pgp",
"my_private_key.asc", "private key pass",
"sender_public_key.asc",
"OUTPUT.txt");
if (validSignature) {
System.out.println("Signature is valid.");
} else {
System.out.println("!Signature is invalid!");
}
}
}
2) Decrypt file with keys located in a KeyStore
We must specify our password for the private key that will be used to decrypt the file (the library searches for a key with Key ID equal to the one used to encrypt the file). For the verification a public key with Key ID equal to the one in the digital signature is searched among the public keys stored in the KeyStore.
import com.didisoft.pgp.KeyStore;
import com.didisoft.pgp.PGPLib;
public class KeystoreDecryptAndVerifyFile {
public static void main(String[] args) throws Exception{
// create an instance of the KeyStore
KeyStore keyStore = new KeyStore("pgp.keystore", "changeit");
// initialize the library
PGPLib pgp = new PGPLib();
// our private decryption key password
String privateKeyPassword = "changeit";
boolean validSignature =
pgp.decryptAndVerifyFile("encrypted.pgp",
keyStore,
privateKeyPassword,
"OUTPUT.txt");
if (validSignature) {
System.out.println("Signature is valid.");
} else {
System.out.println("Signature is invalid!");
}
}
}
3) Decrypt stream with keys supplied as streams
This method gives more freedom on how the encrypted data and OpenPGP keys are stored.
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import com.didisoft.pgp.PGPLib;
public class DecryptAndVerifyStream {
public static void main(String[] args) throws Exception{
// create an instance of the library
PGPLib pgp = new PGPLib();
// obtain a signed and encrypted data stream
InputStream encryptedStream = new FileInputStream("encrypted.pgp");
InputStream privateKeyStream = new FileInputStream("private.key");
String privateKeyPassword = "changeit";
InputStream senderPublicKeyStream = new FileInputStream("public.key");
// specify the destination stream of the decrypted data
OutputStream decryptedStream = new FileOutputStream("OUTPUT.txt");
boolean validSignature =
pgp.decryptAndVerifyStream(encryptedStream,
privateKeyStream, privateKeyPassword,
senderPublicKeyStream,
decryptedStream);
if (validSignature) {
System.out.println("Signature is valid.");
} else {
System.out.println("Signature is invalid!");
}
}
}
4) Decrypt stream with keys located in a KeyStore
This example is equivalent to the decrypt above, only the encrypted data and the decrypted output are streams.
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 KeyStoreDecryptAndVerifyStream {
public static void main(String[] args) throws Exception{
// create an instance of the KeyStore
KeyStore keyStore = new KeyStore("pgp.keystore", "changeit");
// initialize the library
PGPLib pgp = new PGPLib();
// our private decryption key password
String privateKeyPassword = "changeit";
// obtain an encrypted stream
InputStream encryptedStream = new FileInputStream("encrypted.pgp");
// specify the decrypted output stream
OutputStream decryptedStream = new FileOutputStream("OUTPUT.txt");
boolean validSignature =
pgp.decryptAndVerifyStream(encryptedStream,
keyStore,
privateKeyPassword,
decryptedStream);
if (validSignature) {
System.out.println("Signature is valid.");
} else {
System.out.println("Signature is invalid!");
}
}
}
5) Exception Handling
We can simply catch java.io.IOException and com.didisoft.PGPException. If we are interested to identify more deeply what has gone wrong, we can catch a number of PGPException sub classes beforehand.
Check the example below for a list of the expected exception sub classes.
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.decryptAndVerify...
} 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 (NoPublicKeyFoundException e) {
// if the passed public key file does not contain a public key or 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 (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
}
}
}