Package org.c02e.jpgpj
Class Decryptor
- java.lang.Object
-
- org.c02e.jpgpj.Decryptor
-
- All Implemented Interfaces:
java.lang.Cloneable
public class Decryptor extends java.lang.Object implements java.lang.Cloneable
Decrypts and verifies PGP messages using the decryption and verificationKey
s supplied on this object'sRing
.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), usesetSymmetricPassphrase(java.lang.String)
to supply the passphrase.Here's an example of Bob decrypting and verifying an encrypted file that was signed by Alice:
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):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") );
gpg --decrypt --output path/back-to/plaintext.txt path/to/ciphertext.txt.gpg
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
Decryptor.VerificationType
Type of signature verification done by decryptor.protected class
Decryptor.Verifier
Helper for verifying a given message signature.
-
Field Summary
Fields Modifier and Type Field Description protected int
copyFileBufferSize
static int
DEFAULT_COPY_FILE_BUFFER_SIZE
static boolean
DEFAULT_LOGGING_ENABLED
static int
DEFAULT_MAX_FILE_BUFFER_SIZE
static boolean
DEFAULT_VERIFICATION_REQUIRED
static Decryptor.VerificationType
DEFAULT_VERIFICATION_TYPE
protected org.slf4j.Logger
log
protected boolean
loggingEnabled
protected int
maxFileBufferSize
protected Ring
ring
protected java.lang.String
symmetricPassphrase
Deprecated.Null unless explicitly set by user.protected char[]
symmetricPassphraseChars
protected boolean
verificationRequired
Deprecated.UseverificationType
instead.protected Decryptor.VerificationType
verificationType
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory
buildPublicKeyDecryptor(Subkey subkey)
Builds a symmetric-encryption decryptor for the specified subkey.protected org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory
buildSymmetricKeyDecryptor(char[] passphraseChars)
Builds a symmetric-key decryptor for the specified passphrase.protected java.util.List<Decryptor.Verifier>
buildVerifiers(java.util.Iterator<?> signatures)
Builds aDecryptor.Verifier
for each specified signature for which a verification key is available.void
clearSecrets()
Zeroes-out the cached passphrase for all keys, and releases the extracted private key material for garbage collection.Decryptor
clone()
protected long
copy(java.io.InputStream i, java.io.OutputStream o, java.util.List<Decryptor.Verifier> verifiers)
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).FileMetadata
decrypt(java.io.File ciphertext, java.io.File plaintext)
Decrypts the first specified file to the output location specified by the second file, and (ifisVerificationRequired()
) verifies its signatures.FileMetadata
decrypt(java.io.InputStream ciphertext, java.io.OutputStream plaintext)
Decrypts the specified PGP message into the specified output stream, and (ifisVerificationRequired()
) verifies the message signatures.FileMetadata
decrypt(java.nio.file.Path ciphertext, java.nio.file.Path plaintext)
Decrypts the first specified file to the output location specified by the second file, and (ifisVerificationRequired()
) verifies its signatures.protected java.io.InputStream
decrypt(java.util.Iterator<?> data)
Decrypts the encrypted data as the returned input stream.protected java.io.InputStream
decrypt(org.bouncycastle.openpgp.PGPPBEEncryptedData data)
Decrypts the encrypted data as the returned input stream.protected java.io.InputStream
decrypt(org.bouncycastle.openpgp.PGPPublicKeyEncryptedData data, Subkey subkey)
Decrypts the encrypted data as the returned input stream.DecryptionResult
decryptWithFullDetails(java.io.InputStream ciphertext, java.io.OutputStream plaintext)
Decrypts the specified PGP message into the specified output stream, including the armored headers (if stream was armored and contained any such headers).byte[]
getCopyBuffer()
Internal buffer for copying decrypted plaintext into the output stream.int
getCopyFileBufferSize()
int
getMaxFileBufferSize()
Ring
getRing()
java.lang.String
getSymmetricPassphrase()
char[]
getSymmetricPassphraseChars()
Decryptor.VerificationType
getVerificationType()
Type of signature verification.protected org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider
getVerifierProvider()
Helper for signature verification.boolean
isLoggingEnabled()
protected boolean
isUsableForDecryption(Subkey subkey)
boolean
isVerificationRequired()
protected void
matchSignatures(java.util.Iterator<org.bouncycastle.openpgp.PGPSignature> signatures, java.util.List<Decryptor.Verifier> verifiers)
Matches the specified trailing signatures to the specified verifiers.protected java.util.Iterator<?>
parse(java.io.InputStream stream)
Separates stream into PGP packets.void
setCopyFileBufferSize(int copyFileBufferSize)
void
setLoggingEnabled(boolean enabled)
void
setMaxFileBufferSize(int maxFileBufferSize)
Decryptor will choose the most appropriate read/write buffer size for each file.void
setRing(Ring x)
void
setSymmetricPassphrase(java.lang.String x)
void
setSymmetricPassphraseChars(char[] x)
void
setVerificationRequired(boolean x)
void
setVerificationType(Decryptor.VerificationType x)
Type of signature verification.protected java.io.InputStream
unarmor(java.io.InputStream stream)
Wraps stream with ArmoredInputStream if necessary (to convert ASCII-armored content back into binary data).protected java.util.List<FileMetadata>
unpack(java.util.Iterator<?> packets, java.io.OutputStream plaintext)
Recursively unpacks the pgp message packets, writing the decrypted message content into the output stream.protected void
verify(java.util.List<Decryptor.Verifier> verifiers, java.util.List<FileMetadata> meta)
Verifies each verifier's signature, and adds keys with verified signatures to the file metadata.Decryptor
withCopyFileBufferSize(int copyFileBufferSize)
Decryptor
withLoggingEnabled(boolean enabled)
Decryptor
withMaxFileBufferSize(int maxFileBufferSize)
Decryptor
withRing(Ring x)
Decryptor
withSymmetricPassphrase(java.lang.String x)
Decryptor
withSymmetricPassphraseChars(char[] x)
Decryptor
withVerificationRequired(boolean x)
Decryptor
withVerificationType(Decryptor.VerificationType x)
Type of signature verification.java.io.InputStream
wrapSourceInputStream(java.io.InputStream sourceStream, long inputSize)
java.io.OutputStream
wrapTargetOutputStream(java.io.OutputStream targetStream, long inputSize)
-
-
-
Field Detail
-
DEFAULT_MAX_FILE_BUFFER_SIZE
public static final int DEFAULT_MAX_FILE_BUFFER_SIZE
- See Also:
- Constant Field Values
-
DEFAULT_VERIFICATION_TYPE
public static final Decryptor.VerificationType DEFAULT_VERIFICATION_TYPE
-
DEFAULT_VERIFICATION_REQUIRED
public static final boolean DEFAULT_VERIFICATION_REQUIRED
- See Also:
- Constant Field Values
-
DEFAULT_COPY_FILE_BUFFER_SIZE
public static final int DEFAULT_COPY_FILE_BUFFER_SIZE
- See Also:
- Constant Field Values
-
DEFAULT_LOGGING_ENABLED
public static final boolean DEFAULT_LOGGING_ENABLED
- See Also:
- Constant Field Values
-
verificationType
protected Decryptor.VerificationType verificationType
-
verificationRequired
@Deprecated protected boolean verificationRequired
Deprecated.UseverificationType
instead.
-
symmetricPassphraseChars
protected char[] symmetricPassphraseChars
-
symmetricPassphrase
@Deprecated protected java.lang.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
-
-
Method Detail
-
getVerificationType
public Decryptor.VerificationType getVerificationType()
Type of signature verification. Defaults toDecryptor.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 totrue
.- See Also:
DEFAULT_VERIFICATION_REQUIRED
-
withVerificationRequired
public Decryptor withVerificationRequired(boolean x)
- See Also:
setVerificationRequired(boolean)
-
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 (orsetSymmetricPassphraseChars(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 untilclearSecrets()
is called (orsetSymmetricPassphraseChars(char[])
is called again with a different passphrase, and then the char[] will be zeroed.
-
withSymmetricPassphraseChars
public Decryptor withSymmetricPassphraseChars(char[] x)
- See Also:
setSymmetricPassphraseChars(char[])
-
getSymmetricPassphrase
public java.lang.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:
getSymmetricPassphraseChars()
-
setSymmetricPassphrase
public void setSymmetricPassphrase(java.lang.String x)
- Parameters:
x
- Passphrase to use to decrypt with a symmetric key; or empty string. PrefersetSymmetricPassphraseChars(char[])
to avoid creating extra copies of the passphrase in memory that cannot be cleaned up.- See Also:
setSymmetricPassphraseChars(char[])
-
withSymmetricPassphrase
public Decryptor withSymmetricPassphrase(java.lang.String x)
- See Also:
setSymmetricPassphrase(String)
-
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:
DEFAULT_MAX_FILE_BUFFER_SIZE
-
withMaxFileBufferSize
public Decryptor withMaxFileBufferSize(int maxFileBufferSize)
- See Also:
setMaxFileBufferSize(int)
-
getCopyFileBufferSize
public int getCopyFileBufferSize()
- Returns:
- Internal buffer size used to copy data from input ciphertext stream to output plaintext stream internally
- See Also:
DEFAULT_COPY_FILE_BUFFER_SIZE
,getCopyBuffer()
-
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:
DEFAULT_COPY_FILE_BUFFER_SIZE
,getCopyBuffer()
-
withCopyFileBufferSize
public Decryptor withCopyFileBufferSize(int copyFileBufferSize)
- See Also:
setCopyFileBufferSize(int)
-
setRing
public void setRing(Ring x)
- Parameters:
x
- KeysRing
to use for decryption and verification.
-
withRing
public Decryptor withRing(Ring x)
- See Also:
setRing(Ring)
-
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:
setLoggingEnabled(boolean)
-
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(java.io.File ciphertext, java.io.File plaintext) throws java.io.IOException, org.bouncycastle.openpgp.PGPException
Decrypts the first specified file to the output location specified by the second file, and (ifisVerificationRequired()
) 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:
java.io.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 thegetSymmetricPassphrase()
.DecryptionException
- if the message was not encrypted for any of the keys supplied for decryption.VerificationException
- ifisVerificationRequired()
and the message was not signed by any of the keys supplied for verification.
-
decrypt
public FileMetadata decrypt(java.nio.file.Path ciphertext, java.nio.file.Path plaintext) throws java.io.IOException, org.bouncycastle.openpgp.PGPException
Decrypts the first specified file to the output location specified by the second file, and (ifisVerificationRequired()
) 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:
java.io.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 thegetSymmetricPassphrase()
.DecryptionException
- if the message was not encrypted for any of the keys supplied for decryption.VerificationException
- ifisVerificationRequired()
and the message was not signed by any of the keys supplied for verification.
-
wrapSourceInputStream
public java.io.InputStream wrapSourceInputStream(java.io.InputStream sourceStream, long inputSize) throws java.io.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:
java.io.IOException
- If failed to generate the wrapper
-
wrapTargetOutputStream
public java.io.OutputStream wrapTargetOutputStream(java.io.OutputStream targetStream, long inputSize) throws java.io.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:
java.io.IOException
- If failed to generate the wrapper
-
decrypt
public FileMetadata decrypt(java.io.InputStream ciphertext, java.io.OutputStream plaintext) throws java.io.IOException, org.bouncycastle.openpgp.PGPException
Decrypts the specified PGP message into the specified output stream, and (ifisVerificationRequired()
) 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:
java.io.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 thegetSymmetricPassphrase()
.DecryptionException
- if the message was not encrypted for any of the keys supplied for decryption.VerificationException
- ifisVerificationRequired()
and the message was not signed by any of the keys supplied for verification.- See Also:
decryptWithFullDetails
-
decryptWithFullDetails
public DecryptionResult decryptWithFullDetails(java.io.InputStream ciphertext, java.io.OutputStream plaintext) throws java.io.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). IfisVerificationRequired()
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 targetOutputStream
- Returns:
- The
DecryptionResult
containing all relevant information that could be extracted from the encrypted data - including metadata, armored headers (if any), etc... - Throws:
java.io.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 thegetSymmetricPassphrase()
.DecryptionException
- if the message was not encrypted for any of the keys supplied for decryption.VerificationException
- ifisVerificationRequired()
and the message was not signed by any of the keys supplied for verification.
-
unpack
protected java.util.List<FileMetadata> unpack(java.util.Iterator<?> packets, java.io.OutputStream plaintext) throws java.io.IOException, org.bouncycastle.openpgp.PGPException
Recursively unpacks the pgp message packets, writing the decrypted message content into the output stream.- Throws:
java.io.IOException
org.bouncycastle.openpgp.PGPException
-
buildVerifiers
protected java.util.List<Decryptor.Verifier> buildVerifiers(java.util.Iterator<?> signatures) throws org.bouncycastle.openpgp.PGPException
Builds aDecryptor.Verifier
for each specified signature for which a verification key is available.- Throws:
org.bouncycastle.openpgp.PGPException
-
matchSignatures
protected void matchSignatures(java.util.Iterator<org.bouncycastle.openpgp.PGPSignature> signatures, java.util.List<Decryptor.Verifier> verifiers)
Matches the specified trailing signatures to the specified verifiers.
-
decrypt
protected java.io.InputStream decrypt(java.util.Iterator<?> data) throws java.io.IOException, org.bouncycastle.openpgp.PGPException
Decrypts the encrypted data as the returned input stream.- Throws:
java.io.IOException
org.bouncycastle.openpgp.PGPException
-
decrypt
protected java.io.InputStream decrypt(org.bouncycastle.openpgp.PGPPublicKeyEncryptedData data, Subkey subkey) throws java.io.IOException, org.bouncycastle.openpgp.PGPException
Decrypts the encrypted data as the returned input stream.- Throws:
java.io.IOException
org.bouncycastle.openpgp.PGPException
-
decrypt
protected java.io.InputStream decrypt(org.bouncycastle.openpgp.PGPPBEEncryptedData data) throws java.io.IOException, org.bouncycastle.openpgp.PGPException
Decrypts the encrypted data as the returned input stream.- Throws:
java.io.IOException
org.bouncycastle.openpgp.PGPException
-
copy
protected long copy(java.io.InputStream i, java.io.OutputStream o, java.util.List<Decryptor.Verifier> verifiers) throws java.io.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:
java.io.IOException
org.bouncycastle.openpgp.PGPException
-
verify
protected void verify(java.util.List<Decryptor.Verifier> verifiers, java.util.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 java.io.InputStream unarmor(java.io.InputStream stream) throws java.io.IOException, org.bouncycastle.openpgp.PGPException
Wraps stream with ArmoredInputStream if necessary (to convert ASCII-armored content back into binary data).- Throws:
java.io.IOException
org.bouncycastle.openpgp.PGPException
-
parse
protected java.util.Iterator<?> parse(java.io.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 classjava.lang.Object
-
-