Class Decryptor

java.lang.Object
org.c02e.jpgpj.Decryptor
All Implemented Interfaces:
Cloneable

public class Decryptor extends Object implements Cloneable
Decrypts and verifies PGP messages using the decryption and verification Keys supplied on this object's Ring.

To turn off verification, setVerificationRequired(boolean) to false. To decrypt a message encrypted with a passphrase (instead of, or in addition to, a public-key pair), use setSymmetricPassphrase(java.lang.String) to supply the passphrase.

Here's an example of Bob decrypting and verifying an encrypted file that was signed by Alice:


 new Decryptor(
     new Key(new File("path/to/my/keys/alice-pub.gpg")),
     new Key(new File("path/to/my/keys/bob-sec.gpg"), "b0bru1z!")
 ).decrypt(
     new File("path/to/ciphertext.txt.gpg"),
     new File("path/back-to/plaintext.txt")
 );
 
This is equivalent to the following `gpg` command (where Bob has a `bob` secret key and an `alice` public key on his keyring, and enters "b0bru1z!" when prompted for his passphrase):

 gpg --decrypt --output path/back-to/plaintext.txt path/to/ciphertext.txt.gpg
 
  • Field Details

    • DEFAULT_MAX_FILE_BUFFER_SIZE

      public static final int DEFAULT_MAX_FILE_BUFFER_SIZE
      See Also:
    • DEFAULT_VERIFICATION_TYPE

      public static final Decryptor.VerificationType DEFAULT_VERIFICATION_TYPE
    • DEFAULT_VERIFICATION_REQUIRED

      public static final boolean DEFAULT_VERIFICATION_REQUIRED
      See Also:
    • DEFAULT_COPY_FILE_BUFFER_SIZE

      public static final int DEFAULT_COPY_FILE_BUFFER_SIZE
      See Also:
    • DEFAULT_LOGGING_ENABLED

      public static final boolean DEFAULT_LOGGING_ENABLED
      See Also:
    • verificationType

      protected Decryptor.VerificationType verificationType
    • verificationRequired

      @Deprecated protected boolean verificationRequired
      Deprecated.
      Use verificationType instead.
    • symmetricPassphraseChars

      protected char[] symmetricPassphraseChars
    • symmetricPassphrase

      @Deprecated protected String symmetricPassphrase
      Deprecated.
      Null unless explicitly set by user.
    • maxFileBufferSize

      protected int maxFileBufferSize
    • copyFileBufferSize

      protected int copyFileBufferSize
    • loggingEnabled

      protected boolean loggingEnabled
    • ring

      protected Ring ring
    • log

      protected final org.slf4j.Logger log
  • Constructor Details

    • Decryptor

      public Decryptor()
      Constructs a decryptor with an empty key ring.
    • Decryptor

      public Decryptor(Ring ring)
      Constructs a decryptor with the specified key ring.
    • Decryptor

      public Decryptor(Key... keys)
      Constructs a decryptor with the specified keys.
  • Method Details

    • getVerificationType

      public Decryptor.VerificationType getVerificationType()
      Type of signature verification. Defaults to Decryptor.VerificationType.Required.
    • setVerificationType

      public void setVerificationType(Decryptor.VerificationType x)
      Type of signature verification.
    • withVerificationType

      public Decryptor withVerificationType(Decryptor.VerificationType x)
      Type of signature verification.
    • isVerificationRequired

      public boolean isVerificationRequired()
      Returns:
      true to require messages be signed with at least one key from ring. Defaults to true.
    • setVerificationRequired

      public void setVerificationRequired(boolean x)
      Parameters:
      x - true to require messages be signed with at least one key from ring. Defaults to true.
      See Also:
    • withVerificationRequired

      public Decryptor withVerificationRequired(boolean x)
      See Also:
    • getSymmetricPassphraseChars

      public char[] getSymmetricPassphraseChars()
      Returns:
      Passphrase to use to decrypt with a symmetric key; or empty char[]. Note that this char[] itself (and not a copy) will be cached and used until clearSecrets() is called (or setSymmetricPassphraseChars(char[]) is called again with a different passphrase, and then the char[] will be zeroed.
    • setSymmetricPassphraseChars

      public void setSymmetricPassphraseChars(char[] x)
      Parameters:
      x - Passphrase to use to decrypt with a symmetric key; or empty char[]. Note that this char[] itself (and not a copy) will be cached and used until clearSecrets() is called (or setSymmetricPassphraseChars(char[]) is called again with a different passphrase, and then the char[] will be zeroed.
    • withSymmetricPassphraseChars

      public Decryptor withSymmetricPassphraseChars(char[] x)
      See Also:
    • getSymmetricPassphrase

      public String getSymmetricPassphrase()
      Returns:
      Passphrase to use to decrypt with a symmetric key; or empty string. Prefer getSymmetricPassphraseChars() to avoid creating extra copies of the passphrase in memory that cannot be cleaned up.
      See Also:
    • setSymmetricPassphrase

      public void setSymmetricPassphrase(String x)
      Parameters:
      x - Passphrase to use to decrypt with a symmetric key; or empty string. Prefer setSymmetricPassphraseChars(char[]) to avoid creating extra copies of the passphrase in memory that cannot be cleaned up.
      See Also:
    • withSymmetricPassphrase

      public Decryptor withSymmetricPassphrase(String x)
      See Also:
    • getMaxFileBufferSize

      public int getMaxFileBufferSize()
    • setMaxFileBufferSize

      public void setMaxFileBufferSize(int maxFileBufferSize)
      Decryptor will choose the most appropriate read/write buffer size for each file. You can set the maximum value here. Defaults to 1MB.
      Parameters:
      maxFileBufferSize - The read/write buffer size
      See Also:
    • withMaxFileBufferSize

      public Decryptor withMaxFileBufferSize(int maxFileBufferSize)
      See Also:
    • getCopyFileBufferSize

      public int getCopyFileBufferSize()
      Returns:
      Internal buffer size used to copy data from input ciphertext stream to output plaintext stream internally
      See Also:
    • setCopyFileBufferSize

      public void setCopyFileBufferSize(int copyFileBufferSize)
      Parameters:
      copyFileBufferSize - Internal buffer size used to copy data from input ciphertext stream to output plaintext stream internally
      See Also:
    • withCopyFileBufferSize

      public Decryptor withCopyFileBufferSize(int copyFileBufferSize)
      See Also:
    • getRing

      public Ring getRing()
      Returns:
      Keys Ring to use for decryption and verification.
    • setRing

      public void setRing(Ring x)
      Parameters:
      x - Keys Ring to use for decryption and verification.
    • withRing

      public Decryptor withRing(Ring x)
      See Also:
    • isLoggingEnabled

      public boolean isLoggingEnabled()
      Returns:
      true if logging a brief summary of the execution every time decryption is executed (e.g. file name/path, size, compression type, etc.). Note: errors/warnings logging are not affected by this setting
    • setLoggingEnabled

      public void setLoggingEnabled(boolean enabled)
      Parameters:
      enabled - true if should log a brief summary of the execution every time decryption is executed (e.g. file name/path, size, compression type, etc.). Note: errors/warnings logging are not affected by this setting
    • withLoggingEnabled

      public Decryptor withLoggingEnabled(boolean enabled)
      See Also:
    • clearSecrets

      public void clearSecrets()
      Zeroes-out the cached passphrase for all keys, and releases the extracted private key material for garbage collection.
    • decrypt

      public FileMetadata decrypt(File ciphertext, File plaintext) throws IOException, org.bouncycastle.openpgp.PGPException
      Decrypts the first specified file to the output location specified by the second file, and (if isVerificationRequired()) verifies its signatures. If a file already exists in the output file's location, it will be deleted. If an exception occurs during decryption, the output file will be deleted.
      Parameters:
      ciphertext - File containing a PGP message, in binary or ASCII Armor format.
      plaintext - File into which to decrypt the message.
      Returns:
      Metadata of original file, and the list of keys that signed the message with a verified signature. The original file metadata values are optional, and may be missing or incorrect.
      Throws:
      IOException - if an IO error occurs reading from or writing to the underlying input or output streams.
      org.bouncycastle.openpgp.PGPException - if the PGP message is not formatted correctly.
      PassphraseException - if an incorrect passphrase was supplied for one of the decryption keys, or as the getSymmetricPassphrase().
      DecryptionException - if the message was not encrypted for any of the keys supplied for decryption.
      VerificationException - if isVerificationRequired() and the message was not signed by any of the keys supplied for verification.
    • decrypt

      public FileMetadata decrypt(Path ciphertext, Path plaintext) throws IOException, org.bouncycastle.openpgp.PGPException
      Decrypts the first specified file to the output location specified by the second file, and (if isVerificationRequired()) verifies its signatures. If a file already exists in the output file's location, it will be deleted. If an exception occurs during decryption, the output file will be deleted.
      Parameters:
      ciphertext - Path to file containing a PGP message, in binary or ASCII Armor format.
      plaintext - Path of the file into which to decrypt the message.
      Returns:
      Metadata of original file, and the list of keys that signed the message with a verified signature. The original file metadata values are optional, and may be missing or incorrect.
      Throws:
      IOException - if an IO error occurs reading from or writing to the underlying input or output streams.
      org.bouncycastle.openpgp.PGPException - if the PGP message is not formatted correctly.
      PassphraseException - if an incorrect passphrase was supplied for one of the decryption keys, or as the getSymmetricPassphrase().
      DecryptionException - if the message was not encrypted for any of the keys supplied for decryption.
      VerificationException - if isVerificationRequired() and the message was not signed by any of the keys supplied for verification.
    • wrapSourceInputStream

      public InputStream wrapSourceInputStream(InputStream sourceStream, long inputSize) throws IOException
      Parameters:
      sourceStream - Original source (ciphertext) InputStream
      inputSize - Expected input (ciphertext) size
      Returns:
      A wrapper buffered stream optimized for the input size according to the current encryptor settings
      Throws:
      IOException - If failed to generate the wrapper
    • wrapTargetOutputStream

      public OutputStream wrapTargetOutputStream(OutputStream targetStream, long inputSize) throws IOException
      Parameters:
      targetStream - Original target (plaintext) OutputStream
      inputSize - Expected input (ciphertext) size
      Returns:
      A wrapper buffered stream optimized for the input size according to the current encryptor settings
      Throws:
      IOException - If failed to generate the wrapper
    • decrypt

      public FileMetadata decrypt(InputStream ciphertext, OutputStream plaintext) throws IOException, org.bouncycastle.openpgp.PGPException
      Decrypts the specified PGP message into the specified output stream, and (if isVerificationRequired()) verifies the message signatures. Does not close or flush the streams.

      Note that the full decrypted content will be written to the output stream before the message is verified, so you may want to buffer the content and not write it to its final destination until this method returns.

      Parameters:
      ciphertext - PGP message, in binary or ASCII Armor format.
      plaintext - Decrypted content.
      Returns:
      Metadata of original file, and the list of keys that signed the message with a verified signature. The original file metadata values are optional, and may be missing or incorrect.
      Throws:
      IOException - if an IO error occurs reading from or writing to the underlying input or output streams.
      org.bouncycastle.openpgp.PGPException - if the PGP message is not formatted correctly.
      PassphraseException - if an incorrect passphrase was supplied for one of the decryption keys, or as the getSymmetricPassphrase().
      DecryptionException - if the message was not encrypted for any of the keys supplied for decryption.
      VerificationException - if isVerificationRequired() and the message was not signed by any of the keys supplied for verification.
      See Also:
    • decryptWithFullDetails

      public DecryptionResult decryptWithFullDetails(InputStream ciphertext, OutputStream plaintext) throws IOException, org.bouncycastle.openpgp.PGPException
      Decrypts the specified PGP message into the specified output stream, including the armored headers (if stream was armored and contained any such headers). If isVerificationRequired() also verifies the message signatures. Note: does not close or flush the streams.
      Parameters:
      ciphertext - PGP message, in binary or ASCII Armor format.
      plaintext - Decrypted content target OutputStream
      Returns:
      The DecryptionResult containing all relevant information that could be extracted from the encrypted data - including metadata, armored headers (if any), etc...
      Throws:
      IOException - if an IO error occurs reading from or writing to the underlying input or output streams.
      org.bouncycastle.openpgp.PGPException - if the PGP message is not formatted correctly.
      PassphraseException - if an incorrect passphrase was supplied for one of the decryption keys, or as the getSymmetricPassphrase().
      DecryptionException - if the message was not encrypted for any of the keys supplied for decryption.
      VerificationException - if isVerificationRequired() and the message was not signed by any of the keys supplied for verification.
    • unpack

      protected List<FileMetadata> unpack(Iterator<?> packets, OutputStream plaintext) throws IOException, org.bouncycastle.openpgp.PGPException
      Recursively unpacks the pgp message packets, writing the decrypted message content into the output stream.
      Throws:
      IOException
      org.bouncycastle.openpgp.PGPException
    • buildVerifiers

      protected List<Decryptor.Verifier> buildVerifiers(Iterator<?> signatures) throws org.bouncycastle.openpgp.PGPException
      Builds a Decryptor.Verifier for each specified signature for which a verification key is available.
      Throws:
      org.bouncycastle.openpgp.PGPException
    • matchSignatures

      protected void matchSignatures(Iterator<org.bouncycastle.openpgp.PGPSignature> signatures, List<Decryptor.Verifier> verifiers)
      Matches the specified trailing signatures to the specified verifiers.
    • decrypt

      protected InputStream decrypt(Iterator<?> data) throws IOException, org.bouncycastle.openpgp.PGPException
      Decrypts the encrypted data as the returned input stream.
      Throws:
      IOException
      org.bouncycastle.openpgp.PGPException
    • decrypt

      protected InputStream decrypt(org.bouncycastle.openpgp.PGPPublicKeyEncryptedData data, Subkey subkey) throws IOException, org.bouncycastle.openpgp.PGPException
      Decrypts the encrypted data as the returned input stream.
      Throws:
      IOException
      org.bouncycastle.openpgp.PGPException
    • decrypt

      protected InputStream decrypt(org.bouncycastle.openpgp.PGPPBEEncryptedData data) throws IOException, org.bouncycastle.openpgp.PGPException
      Decrypts the encrypted data as the returned input stream.
      Throws:
      IOException
      org.bouncycastle.openpgp.PGPException
    • copy

      protected long copy(InputStream i, OutputStream o, List<Decryptor.Verifier> verifiers) throws IOException, org.bouncycastle.openpgp.PGPException
      Copies the content from the specified input stream to the specified output stream, while also checking the content with the specified list of verifiers (if verification required).
      Throws:
      IOException
      org.bouncycastle.openpgp.PGPException
    • verify

      protected void verify(List<Decryptor.Verifier> verifiers, List<FileMetadata> meta) throws org.bouncycastle.openpgp.PGPException
      Verifies each verifier's signature, and adds keys with verified signatures to the file metadata.
      Throws:
      org.bouncycastle.openpgp.PGPException
    • unarmor

      protected InputStream unarmor(InputStream stream) throws IOException, org.bouncycastle.openpgp.PGPException
      Wraps stream with ArmoredInputStream if necessary (to convert ASCII-armored content back into binary data).
      Throws:
      IOException
      org.bouncycastle.openpgp.PGPException
    • parse

      protected Iterator<?> parse(InputStream stream)
      Separates stream into PGP packets.
      See Also:
      • PGPObjectFactory
    • getVerifierProvider

      protected org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider getVerifierProvider()
      Helper for signature verification.
    • isUsableForDecryption

      protected boolean isUsableForDecryption(Subkey subkey)
    • buildPublicKeyDecryptor

      protected org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory buildPublicKeyDecryptor(Subkey subkey) throws org.bouncycastle.openpgp.PGPException
      Builds a symmetric-encryption decryptor for the specified subkey.
      Throws:
      org.bouncycastle.openpgp.PGPException
    • buildSymmetricKeyDecryptor

      protected org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory buildSymmetricKeyDecryptor(char[] passphraseChars) throws org.bouncycastle.openpgp.PGPException
      Builds a symmetric-key decryptor for the specified passphrase.
      Throws:
      org.bouncycastle.openpgp.PGPException
    • getCopyBuffer

      public byte[] getCopyBuffer()
      Internal buffer for copying decrypted plaintext into the output stream.
    • clone

      public Decryptor clone()
      Overrides:
      clone in class Object