How to encrypt PDF using a certificate?

Tags: Certificate encryptionencryptioncertificateiText 7

We need to encrypt a PDF with a certificate. I've found something using iText some months ago, but I cannot find it any more. The certs are on a smart card.

Posted on StackOverflow on May 21, 2014 by user2946593

Encrypting a PDF is done with a public certificate. Once a PDF is encrypted, only the person with the corresponding private certificate can open the PDF. In your scenario, this would mean that only the person who owns the smart card can open the document.

First you need to extract the public certificate from the smart card. The main question here is: do you want to do this in Java? If so, do you want to do this using PKCS#11? Using MSCAPI? Using a smart card API? I honestly don't think that's what you want to do. I think you want the owners of the smart card to extract their public certificate manually and to send it to you. If this assumption is wrong, you need to post another question: how to get a public certificate from a smart card.

Once you have this certificate, you can encrypt the PDF like it's shown in EncryptWithCertificate example:

protected void encryptPdf(String cer, String dest) throws Exception {
    Security.addProvider(new BouncyCastleProvider());
    Certificate cert = getPublicCertificate(cer);
    PdfWriter writer = new PdfWriter(dest, new WriterProperties()
            .setPublicKeyEncryption(
                    new Certificate[]{cert},
                    new int[]{EncryptionConstants.ALLOW_PRINTING},
                    EncryptionConstants.ENCRYPTION_AES_256));
    PdfDocument pdfDoc = new PdfDocument(writer);
    Document doc = new Document(pdfDoc);
    doc.add(new Paragraph("My secret hello"));
    doc.close();
}
 
public Certificate getPublicCertificate(String path) throws IOException, CertificateException {
    FileInputStream is = new FileInputStream(path);
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
    return cert;
}

As you see, we set WriterProperties using a Certificate instance. The public certificate is stored in the file, that your end user extracted from the smart card.

Click this link if you want to see how to answer this question in iText 5.