org.faceless.pdf2
Class PublicKeyEncryptionHandler

java.lang.Object
  extended byorg.faceless.pdf2.EncryptionHandler
      extended byorg.faceless.pdf2.PublicKeyEncryptionHandler
All Implemented Interfaces:
Cloneable

public final class PublicKeyEncryptionHandler
extends EncryptionHandler

The PublicKeyEncryptionHandler can be used to encrypt and decrypt documents using public/private key Encryption, so documents can only be opened by certain individuals. It requires Java 1.4 or later, as it uses the javax.crypto package. The resulting documents can be opened in Acrobat 5 or later with the appropriate private key.

We're going to assume you're familiar with public key cryptography if you're using this class, and instead jump straight in and give a couple of examples showing how to decrypt and encrypt a document. First, some important notes:

  1. This handler only works with Java 1.4 or above
  2. You must download and install the unrestricted policy files for the Sun JCE. You can download these from the same place you download Java - for Suns current 1.4.2 release, they are available at http://java.sun.com/j2se/1.4.2/download.html. If they're not installed, you'll see an exception like: java.lang.SecurityException: Unsupported keysize or algorithm parameters
  3. You will need a JCE provider that implements the ciphers you need. We recommend the Bouncy Castle package, available at http://www.bouncycastle.org, which we've developed and tested with, but it should work with any JCE provider. Make sure it's installed and listed as a provider in your code by calling the Security.addProvider(java.security.Provider) method like so: Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

Once these steps are done, to encrypt a document you need the X.509 certificate of the person you're sending it to. Typically you'd get this from a KeyStore, as in this example:

 KeyStore keystore = KeyStore.getInstance("PKCS12");
 keystore.load(new FileInputStream("keystore.p12"), "password".toCharArray());
 X509Certificate cert = (X509Certificate)keystore.getCertificate("john");

 PublicKeyEncryptionHandler handler = new PublicKeyEncryptionHandler(5);
 handler.addRecipient(cert, StandardEncryptionHandler.PRINT_HIGHRES,
                            StandardEncryptionHandler.CHANGE_ALL,
                            StandardEncryptionHandler.EXTRACT_ALL);

 PDF.setEncryptionHandler(handler);
 
You can also use the FormSignature.loadPKCS7KeyStore(java.io.InputStream) method to load your X.509 certificates from a PKCS#7 object.

For decrypting a document, you will need a KeyStore containing a private key that matches the public key used to encrypt the document. Typically this will be done like so:

 KeyStore keystore = KeyStore.getInstance("PKCS12");
 keystore.load(new FileInputStream("keystore.p12"), "storepassword".toCharArray());
 EncryptionHandler handler = new PublicKeyEncryptionHandler(keystore,
                                                            null,
                                                            "keypassword".toCharArray());
 
 PDF pdf = new PDF(new PDFReader(new File("encrypted.pdf"), handler));
 

Since:
2.2.5
See Also:
FormSignature, PDFReader.PDFReader(InputStream,EncryptionHandler), StandardEncryptionHandler

Constructor Summary
PublicKeyEncryptionHandler(int acrobatversion)
          Create a new PublicKeyEncryptionHandler for encrypting a document.
PublicKeyEncryptionHandler(KeyStore keystore, String alias, char[] password)
          Create a new PublicKeyEncryptionHandler for decrypting a document encrypted with the Adobe.PubSec public key encryption handler.
 
Method Summary
 void addRecipient(X509Certificate recipient, int print, int extraction, int change)
          Add a recipient to the list of people that can open the document
 void finishedDecrypt()
          This method is called after the PDF has been read.
 void finishedEncrypt()
          This method is called after the PDF has been written.
 OutputStream getDecryptionStream(OutputStream out)
          Return a FilterOutputStream that will decrypt anything written to it.
 OutputStream getEncryptionStream(OutputStream out)
          Return a FilterOutputStream that will encrypt anything written to it.
 String getFilterName()
          Return the name of the "Filter" field in the Encryption dictionary.
 String getSubFilterName()
          Return the name of the "Subfilter" field in the Encryption dictionary.
 boolean isRequired()
          This method should return true if the document needs to be encrypted.
 void prepareToDecrypt()
          This method is called just before the PDF is read in.
 void prepareToEncrypt()
          This method is called when the PDF is about to be written out.
 void setObject(int object, int generation)
          This method is called just before each object is encrypted.
 
Methods inherited from class org.faceless.pdf2.EncryptionHandler
clone, containsKey, getArrayValueSize, getBooleanValue, getDictionaryValueKeys, getFileId, getNameValue, getNumericValue, getStringValue, getTextStringValue, putArrayValue, putBooleanValue, putDictionaryValue, putNameValue, putNumericValue, putStringValue, putTextStringValue, setFileId
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

PublicKeyEncryptionHandler

public PublicKeyEncryptionHandler(KeyStore keystore,
                                  String alias,
                                  char[] password)
Create a new PublicKeyEncryptionHandler for decrypting a document encrypted with the Adobe.PubSec public key encryption handler.

Parameters:
keystore - the KeyStore containing the private key to decrypt the document with
alias - the alias of the key to use, or null to use the first key that fits
password - the password to decrypt the private key, or null if no password is required
Since:
2.2.5

PublicKeyEncryptionHandler

public PublicKeyEncryptionHandler(int acrobatversion)
Create a new PublicKeyEncryptionHandler for encrypting a document. Recipients can be added using the addRecipient() method. The version number specifies the minimum release of Acrobat required to open the document - currently the only valid value is "5", which means any documents created using the handler can be opened in Acroabt 5 or later.

Parameters:
acrobatversion - the version of Acrobat that is being targeted. Must be 5.
Since:
2.2.5
Method Detail

addRecipient

public void addRecipient(X509Certificate recipient,
                         int print,
                         int extraction,
                         int change)
Add a recipient to the list of people that can open the document

Parameters:
recipient - the X.509 certificate of the recipient
print - one of StandardEncryptionHandler.PRINT_NONE StandardEncryptionHandler.PRINT_LOWRES StandardEncryptionHandler.PRINT_HIGHRES
extraction - one of StandardEncryptionHandler.EXTRACT_NONE StandardEncryptionHandler.EXTRACT_ACCESSIBILITY StandardEncryptionHandler.EXTRACT_ALL
change - one of StandardEncryptionHandler.CHANGE_NONE StandardEncryptionHandler.CHANGE_LAYOUT StandardEncryptionHandler.CHANGE_FORMS StandardEncryptionHandler.CHANGE_ANNOTATIONS StandardEncryptionHandler.CHANGE_ALL
Since:
2.2.5

getFilterName

public String getFilterName()
Description copied from class: EncryptionHandler
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, the StandardEncryptionHandler class returns "Standard" from this method.

Specified by:
getFilterName in class EncryptionHandler

getSubFilterName

public String getSubFilterName()
Description copied from class: EncryptionHandler
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 return null.

Specified by:
getSubFilterName in class EncryptionHandler

isRequired

public boolean isRequired()
Description copied from class: EncryptionHandler
This method should return true if the document needs to be encrypted. For example, the StandardEncryptionHandler returns false here if and only if no passwords are set and the document is set to allow full access.

Specified by:
isRequired in class EncryptionHandler

setObject

public void setObject(int object,
                      int generation)
Description copied from class: EncryptionHandler
This method is called just before each object is encrypted. It is expected that the values that are passed in are used to change the stream returned by the EncryptionHandler.getEncryptionStream(java.io.OutputStream) and EncryptionHandler.getEncryptionStream(java.io.OutputStream) methods

Specified by:
setObject in class EncryptionHandler

getEncryptionStream

public OutputStream getEncryptionStream(OutputStream out)
Description copied from class: EncryptionHandler
Return a FilterOutputStream that will encrypt anything written to it. The encryption parameters should have already been set by the call to EncryptionHandler.prepareToEncrypt(), which is called once at the start of the render, and EncryptionHandler.setObject(int, int), which is called just before each object is rendered.

Specified by:
getEncryptionStream in class EncryptionHandler

getDecryptionStream

public OutputStream getDecryptionStream(OutputStream out)
Description copied from class: EncryptionHandler
Return a FilterOutputStream that will decrypt anything written to it. The decryption parameters should have already been set by the call to EncryptionHandler.prepareToDecrypt(), which is called once at the start of the PDF read, and EncryptionHandler.setObject(int, int), which is called just before each object is read.

Specified by:
getDecryptionStream in class EncryptionHandler

prepareToDecrypt

public void prepareToDecrypt()
                      throws IOException
Description copied from class: EncryptionHandler
This method is called just before the PDF is read in. It is expected that this method will read various parameters from the Encrypt dictionary by way of the various get... methods, and use them and the value of EncryptionHandler.getFileId() to set its internal state so that it's ready to start decryption. It may throw an IOException if these parameters are invalid, in which case the document cannot be read.

Specified by:
prepareToDecrypt in class EncryptionHandler
Throws:
IOException

prepareToEncrypt

public void prepareToEncrypt()
                      throws IOException
Description copied from class: EncryptionHandler
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 the Encrypt dictionary (including the "Filter" field) by way of the various put... methods, and will use these and the value of EncryptionHandler.getFileId() to set its internal state so that it's ready to start encryption. It may throw an IOException if these parameters are in any way invalid, in which case the document cannot be written.

Specified by:
prepareToEncrypt in class EncryptionHandler
Throws:
IOException

finishedEncrypt

public void finishedEncrypt()
Description copied from class: EncryptionHandler
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.

Specified by:
finishedEncrypt in class EncryptionHandler

finishedDecrypt

public void finishedDecrypt()
Description copied from class: EncryptionHandler
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.

Specified by:
finishedDecrypt in class EncryptionHandler


Copyright © 2001-2004 Big Faceless Organization