Class EncryptionHandler
- java.lang.Object
-
- org.faceless.pdf2.EncryptionHandler
-
- All Implemented Interfaces:
java.lang.Cloneable
- Direct Known Subclasses:
PublicKeyEncryptionHandler
,StandardEncryptionHandler
public abstract class EncryptionHandler extends java.lang.Object implements java.lang.Cloneable
An EncryptionHandler is the abstract superclass of all algorithms that are used to encrypt a PDF document before saving. Encryption is required to enforce any sorts of restriction on a PDF, whether it be that it requires a password to open, it can only be opened by a user posessing a certain private key, or just that it can't be printed or altered.
Although currently the PDF library is only supplied with a single implementation of this class (the
StandardEncryptionHandler
), it is possible for end-users to implement their own versions of this class to allow PDF's to be created for custom encryption handlers, such as might be required for e-Books (for example).The following information is for those who will be creating a concrete implementation of this class.
When encrypting, the
PDF.render(java.io.OutputStream)
method will call theprepareToEncrypt()
method, followed by n number of calls togetEncryptionStream(java.io.OutputStream, int, int)
and finally followed by a call tofinishedEncrypt()
(the decryption process is the same, except substitute the word "Decrypt" forEncrypt
in the method names above).The two
prepare...
methods can store and retrieve values out of theEncrypt
dictionary by calling the variousget...
andput...
methods. These methods expect the key to be specified as a String. At it's simplest, a method call likeputNameValue("Filter", "Standard")
would create a PDF Name object called "Filter" in theEncrypt
dictionary. For nested objects, Arrays and Dictionary objects can be referenced by placing a "." between field names. For example, "MyArray.2.Name" references the object called "Name" in the Dictionary which is the second entry in the "MyArray" array of theEncrypt
dictionary. All objects added this way are "direct" - it is not possible to add indirect objects to the encryption dictionary or it's children.An EncryptionHandler may be used for both decryption and encryption if the document is read and then written again, so it's important that any values read from the
Encrypt
dictionary during theprepareToDecrypt()
method are available to be reused in theprepareToEncrypt()
method.Finally, care needs to be taken about any references to
Object
instances when an instance is cloned - which it will be when a PDF containing an EncryptionHandler is cloned.
-
-
Constructor Summary
Constructors Modifier Constructor Description protected
EncryptionHandler()
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description java.lang.Object
clone()
protected boolean
containsKey(java.lang.String key)
Return true if theEncrypt
dictionary contains the specified keyabstract void
finishedDecrypt()
This method is called after the PDF has been read.abstract void
finishedEncrypt()
This method is called after the PDF has been written.protected int
getArrayValueSize(java.lang.String key)
Return the size of the specified Array from theEncrypt
dictionary, or-1
if no such field existsprotected boolean
getBooleanValue(java.lang.String key)
Return a Boolean from theEncrypt
dictionary as a boolean orfalse
if no such field existsint
getDecryptedStreamLength(int length)
Return the length that an encrypted stream o the specified length would be after decryption.abstract java.io.InputStream
getDecryptionStream(java.io.InputStream in, int object, int generation)
Return aFilterInputStream
that will decrypt anything read from it.protected java.util.Set<java.lang.String>
getDictionaryValueKeys(java.lang.String key)
Return the Set of keys of the specified Dictionary from theEncrypt
dictionary, ornull
if no such field exists.int
getEncryptedStreamLength(int length)
Return the length that a stream of the specified length would be after encryption.abstract java.io.OutputStream
getEncryptionStream(java.io.OutputStream out, int object, int generation)
Return aFilterOutputStream
that will encrypt anything written to it.protected byte[]
getFileId()
This method returns the the file ID of the document, as set bysetFileId(byte[])
.abstract java.lang.String
getFilterName()
Return the name of the "Filter" field in the Encryption dictionary.protected int
getIntegerValue(java.lang.String key)
Return a Number from theEncrypt
dictionary as an integer or0
if no such field existsprotected java.lang.String
getNameValue(java.lang.String key)
Return a Name from theEncrypt
dictionary as a String ornull
if no such field existsprotected float
getNumericValue(java.lang.String key)
Return a Number from theEncrypt
dictionary as a float orFloat.NaN
if no such field existsprotected byte[]
getStringValue(java.lang.String key)
Return a String from theEncrypt
dictionary as a byte array ornull
if no such field existsabstract java.lang.String
getSubFilterName()
Return the name of the "Subfilter" field in the Encryption dictionary.protected java.lang.String
getTextStringValue(java.lang.String key)
Return a Text String from theEncrypt
dictionary as a String ornull
if no such field existsboolean
hasRight(java.lang.String right)
Returns true if the EncryptionHandler wil grant the specified right to the PDF library.boolean
isChanged()
Return true if the PDF has been marked as changedboolean
isEmbeddedFileEncrypted()
This method returns true if Embedded Files in the document should be stored encrypted.boolean
isMetadataEncrypted()
This method returns true if XMP MetaData should be stored encrypted, or false otherwise.abstract boolean
isRequired()
This method should returntrue
if the document needs to be encrypted.boolean
isStreamEncrypted()
This method returns true if Streams in the document should be stored encrypted.boolean
isStringEncrypted()
This method returns true if Strings in the document should be stored encrypted.protected void
markChanged()
This method should be called whenever a field in the EncryptionHandler is changed so that the encryption would be changed.abstract void
prepareToDecrypt()
This method is called just before the PDF is read in.abstract void
prepareToEncrypt()
This method is called when the PDF is about to be written out.protected void
putArrayValue(java.lang.String key)
Add (or replace) an Array to theEncrypt
dictionary.protected void
putBooleanValue(java.lang.String key, boolean val)
Add (or replace) a Boolean to theEncrypt
dictionary.protected void
putDictionaryValue(java.lang.String key)
Add (or replace) a Dictionary to theEncrypt
dictionary.protected void
putNameValue(java.lang.String key, java.lang.String val)
Add (or replace) a Name to theEncrypt
dictionary.protected void
putNumericValue(java.lang.String key, float val)
Add (or replace) a Number to theEncrypt
dictionary.protected void
putStringValue(java.lang.String key, byte[] val)
Add (or replace) a String to theEncrypt
dictionary.protected void
putTextStringValue(java.lang.String key, java.lang.String val)
Add (or replace) a Text String to theEncrypt
dictionary.void
setFileId(byte[] in)
This method is called to set the file ID of the document.
-
-
-
Method Detail
-
getFilterName
public abstract java.lang.String getFilterName()
Return the name of the "Filter" field in the Encryption dictionary. This is used to determine whether an appropriate filter has been supplied by the decryption process. For example, theStandardEncryptionHandler
class returns "Standard" from this method.
-
getSubFilterName
public abstract java.lang.String getSubFilterName()
Return the name of the "Subfilter" field in the Encryption dictionary. This is used to determine whether an appropriate filter has been supplied by the decryption process. As "Subfilter" is an optional field, this method may returnnull
.
-
getEncryptionStream
public abstract java.io.OutputStream getEncryptionStream(java.io.OutputStream out, int object, int generation)
Return aFilterOutputStream
that will encrypt anything written to it. The encryption parameters are set inprepareToEncrypt()
, which is called once at the start of the render.- Parameters:
out
- the OuptutStream that should be written toobject
- the object number of the top-level objectgeneration
- the generation number of the top-level object
-
getDecryptionStream
public abstract java.io.InputStream getDecryptionStream(java.io.InputStream in, int object, int generation)
Return aFilterInputStream
that will decrypt anything read from it. The decryption parameters are set inprepareToDecrypt()
, which is called once at the start of the PDF read.- Parameters:
in
- the InputStream that should be read fromobject
- the object number of the top-level objectgeneration
- the generation number of the top-level object
-
getEncryptedStreamLength
public int getEncryptedStreamLength(int length)
Return the length that a stream of the specified length would be after encryption. Generally this will be the same same as the input length (and that's what this method returns, unless overridden), but for some Encryption algorithms like AES, the size may be rounded up to the nearest block size.- Since:
- 2.4
-
getDecryptedStreamLength
public int getDecryptedStreamLength(int length)
Return the length that an encrypted stream o the specified length would be after decryption. Generally this will be the same as the input length, which is what this method returns unless overridden. However for some encryption algorithms like AES the size will be altered. If an exact number is known this method should return it, or if it's not possible to deduce the decrypted length from the input length this method should return -1.- Since:
- 2.10.3
-
prepareToDecrypt
public abstract void prepareToDecrypt() throws java.io.IOException
This method is called just before the PDF is read in. It is expected that this method will read various parameters from theEncrypt
dictionary by way of the variousget...
methods, and use them and the value ofgetFileId()
to set its internal state so that it's ready to start decryption. It may throw anIOException
if these parameters are invalid, in which case the document cannot be read.- Throws:
java.io.IOException
-
prepareToEncrypt
public abstract void prepareToEncrypt() throws java.io.IOException
This method is called when the PDF is about to be written out. It is expected that this method will write various parameters which have been set by the user to theEncrypt
dictionary (including the "Filter" field) by way of the variousput...
methods, and will use these and the value ofgetFileId()
to set its internal state so that it's ready to start encryption. It may throw anIOException
if these parameters are in any way invalid, in which case the document cannot be written.- Throws:
java.io.IOException
-
finishedDecrypt
public abstract void finishedDecrypt()
This method is called after the PDF has been read. It may be used to clean up any internal state that needs to be cleaned.
-
finishedEncrypt
public abstract void finishedEncrypt()
This method is called after the PDF has been written. It may be used to clean up any internal state that needs to be cleaned.
-
isRequired
public abstract boolean isRequired()
This method should returntrue
if the document needs to be encrypted. For example, theStandardEncryptionHandler
returnsfalse
here if and only if no passwords are set and the document is set to allow full access.
-
isMetadataEncrypted
public boolean isMetadataEncrypted()
This method returns true if XMP MetaData should be stored encrypted, or false otherwise. The default implementation returns true, subclasses should override as necessary.- Since:
- 2.8.2
-
isStringEncrypted
public boolean isStringEncrypted()
This method returns true if Strings in the document should be stored encrypted. By default this method returns true.- Since:
- 2.10.3
-
isStreamEncrypted
public boolean isStreamEncrypted()
This method returns true if Streams in the document should be stored encrypted. By default this method returns true.- Since:
- 2.10.3
-
isEmbeddedFileEncrypted
public boolean isEmbeddedFileEncrypted()
This method returns true if Embedded Files in the document should be stored encrypted. By default this method returns true.- Since:
- 2.10.3
-
markChanged
protected void markChanged()
This method should be called whenever a field in the EncryptionHandler is changed so that the encryption would be changed. This method is required because documents that are both digitally signed and encrypted cannot have their encryption changed without invalidating the signature. When this method is called, if the document contains any signed signatures anIllegalStateException
is called- Throws:
java.lang.IllegalStateException
- if the document has any digital signatures that would be invalidated by this change- Since:
- 2.4
-
isChanged
public boolean isChanged()
Return true if the PDF has been marked as changed- Since:
- 2.18.2
- See Also:
markChanged()
-
setFileId
public void setFileId(byte[] in)
This method is called to set the file ID of the document.
-
hasRight
public boolean hasRight(java.lang.String right)
Returns true if the EncryptionHandler wil grant the specified right to the PDF library. The default implementation of this method returns true, but subclasses will override this method based on the rights applied to the document. This method should always returnsuper.hasRight()
if it doesn't recognise the value of "right"- Parameters:
right
- an interned() String defining the usage right the PDF library is querying.- Since:
- 2.8.2
-
getFileId
protected byte[] getFileId()
This method returns the the file ID of the document, as set bysetFileId(byte[])
.
-
clone
public java.lang.Object clone()
- Overrides:
clone
in classjava.lang.Object
-
containsKey
protected boolean containsKey(java.lang.String key)
Return true if theEncrypt
dictionary contains the specified key
-
getStringValue
protected byte[] getStringValue(java.lang.String key)
Return a String from theEncrypt
dictionary as a byte array ornull
if no such field exists
-
getTextStringValue
protected java.lang.String getTextStringValue(java.lang.String key)
Return a Text String from theEncrypt
dictionary as a String ornull
if no such field exists
-
getNameValue
protected java.lang.String getNameValue(java.lang.String key)
Return a Name from theEncrypt
dictionary as a String ornull
if no such field exists
-
getNumericValue
protected float getNumericValue(java.lang.String key)
Return a Number from theEncrypt
dictionary as a float orFloat.NaN
if no such field exists
-
getIntegerValue
protected int getIntegerValue(java.lang.String key)
Return a Number from theEncrypt
dictionary as an integer or0
if no such field exists
-
getBooleanValue
protected boolean getBooleanValue(java.lang.String key)
Return a Boolean from theEncrypt
dictionary as a boolean orfalse
if no such field exists
-
getArrayValueSize
protected int getArrayValueSize(java.lang.String key)
Return the size of the specified Array from theEncrypt
dictionary, or-1
if no such field exists
-
getDictionaryValueKeys
protected java.util.Set<java.lang.String> getDictionaryValueKeys(java.lang.String key)
Return the Set of keys of the specified Dictionary from theEncrypt
dictionary, ornull
if no such field exists.
-
putStringValue
protected void putStringValue(java.lang.String key, byte[] val)
Add (or replace) a String to theEncrypt
dictionary. A value ofnull
removes the entry.
-
putTextStringValue
protected void putTextStringValue(java.lang.String key, java.lang.String val)
Add (or replace) a Text String to theEncrypt
dictionary. A value ofnull
removes the entry
-
putNumericValue
protected void putNumericValue(java.lang.String key, float val)
Add (or replace) a Number to theEncrypt
dictionary. A value ofFloat.NaN
removes the entry.
-
putNameValue
protected void putNameValue(java.lang.String key, java.lang.String val)
Add (or replace) a Name to theEncrypt
dictionary. A value ofnull
removes the entry.
-
putBooleanValue
protected void putBooleanValue(java.lang.String key, boolean val)
Add (or replace) a Boolean to theEncrypt
dictionary. A value ofnull
removes the entry.
-
putArrayValue
protected void putArrayValue(java.lang.String key)
Add (or replace) an Array to theEncrypt
dictionary.
-
putDictionaryValue
protected void putDictionaryValue(java.lang.String key)
Add (or replace) a Dictionary to theEncrypt
dictionary.
-
-