Skip to main content
Skip table of contents

Support for Message Authentication Code (MAC) integrity protection

With the release of iText 9.0, new functionality was introduced to check the integrity of a PDF file: MAC-based integrity protection.

This is a feature that requires PDF 2.0, and was introduced with the ISO-32004 standard. For more information on this feature, here is a very good technical overview on the PDF Association website. In addition, there is a detailed explanation about the difference between MACs and digital signatures.

To add such a MAC details to a protected PDF file with iText Core, you have to specify the MacProperties() in the WriterProperties (Java/.NET).

Create MAC integrity protection

This is a very simple code sample to add the the new functionality:

JAVA
package com.example;
import java.security.Security;
import com.itextpdf.bouncycastleconnector.BouncyCastleFactoryCreator;
import com.itextpdf.kernel.mac.MacProperties;
import com.itextpdf.kernel.mac.MacProperties.MacDigestAlgorithm;
import com.itextpdf.kernel.pdf.EncryptionConstants;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfVersion;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.WriterProperties;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.Document;

public class Main {
    public static void main(String[] args) throws Exception{
        byte[] USERPASSWORD = "".getBytes();
        byte[] MASTERPASSWORD = "master".getBytes();
        Security.addProvider(BouncyCastleFactoryCreator.getFactory().getProvider());
        //Initialize PDF writer with MacProperties        
        WriterProperties writerProperties = 
            new WriterProperties().setPdfVersion(PdfVersion.PDF_2_0).setStandardEncryption(
                USERPASSWORD, 
                MASTERPASSWORD, 
                0, 
                EncryptionConstants.ENCRYPTION_AES_256,
                new MacProperties(MacDigestAlgorithm.SHA_256));
        PdfWriter writer = new PdfWriter("MacIntegrity.pdf", writerProperties);
        //Initialize PDF document
        PdfDocument pdf = new PdfDocument(writer);
        // Initialize document
        Document document = new Document(pdf);
        //Add paragraph to the document
        document.add(new Paragraph("Hello Mac Integrity!"));
        //Close document
        document.close();
    }
}
C#
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using System.Text;
using iText.Kernel.Mac;
using static iText.Kernel.Mac.MacProperties;
class Program
{
    static void Main() {
        //Initialize PDF writer with MacProperties        
        WriterProperties writerProperties = 
            new WriterProperties().SetPdfVersion(PdfVersion.PDF_2_0).SetStandardEncryption(
                Encoding.ASCII.GetBytes(""), 
                Encoding.ASCII.GetBytes("master") , 
                0,
                EncryptionConstants.ENCRYPTION_AES_256,
                new MacProperties(MacDigestAlgorithm.SHA_256));
        PdfWriter writer = new PdfWriter("MacIntegrity.pdf", writerProperties);
        //Initialize PDF document
        PdfDocument pdf = new PdfDocument(writer);
        // Initialize document
        Document document = new Document(pdf);
        //Add paragraph to the document
        document.Add(new Paragraph("Hello Mac Integrity!"));
        //Close document
        document.Close();
    }
}

Validate MAC integrity

When a PDF file is read, the MAC validation will be processed. When the validation is broken, an exception occurs:

JAVA
package com.example;
import java.security.Security;
import com.itextpdf.bouncycastleconnector.BouncyCastleFactoryCreator;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.ReaderProperties;

public class testMacIntegrity {
    public static void main(String[] args) throws Exception{
        //Initialize PDF writer
        byte[] USERPASSWORD = "".getBytes();
        String inputfile = "MacIntegrity.pdf";
        Security.addProvider(BouncyCastleFactoryCreator.getFactory().getProvider());
         try {
            PdfDocument test = new PdfDocument(
                        new PdfReader(inputfile,
                         new ReaderProperties().setPassword(USERPASSWORD)));
            System.out.println(inputfile + " is valid");
        }
        catch (Exception e) {
            System.out.println("Error: " + e);
        }
    }
}
C#
using iText.Kernel.Pdf;
using System.Text;
class Program
{
    static void Main() {
        string inputfile = "MacIntegrity.pdf";
        byte[] USERPASSWORD = Encoding.ASCII.GetBytes("");
        try {
            PdfDocument test = new PdfDocument(
                        new PdfReader(inputfile,
                        new ReaderProperties().SetPassword(USERPASSWORD)));
            Console.WriteLine(inputfile + " is valid");
        }
        catch (Exception e) {
            Console.WriteLine("Error: " + e);
        }
    }
}
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.