[]
        
(Showing Draft Content)

Security

PDF security can be maintained by controlling access to PDF documents by encrypting PDF and setting permission levels that will prevent unauthorized users from stealing information in your PDF document. For more information on PDF security, see PDF specification 1.7 (Section 7.6.3).

The GcPdf library supports some of the standard security options in the PDF file format. The following section describes the different types of security features.

Encrypt PDF

PDF documents with sensitive or confidential information require encryption to restrict access to intruders. GcPdf provides Security class to encrypt a document and decline access to unauthorized users.

To encrypt a PDF file using Standard Security Handler Revision 4:

  1. Create an object of StandardSecurityHandlerRev4 class.

  2. Set the required properties of the StandardSecurityHandlerRev4 object, such as passwords, encryption algorithm, etc.

  3. Pass the object to the EncryptHandler property of the Security class to encrypt the PDF document.

    public void CreatePDF(Stream stream)
    {
        GcPdfDocument doc = new GcPdfDocument();
        var page = doc.NewPage();
        var g = page.Graphics;
        const float In = 150;
        //Add Encryption
        var std = new StandardSecurityHandlerRev4();
        std.OwnerPassword = "abc";
        std.UserPassword = "qwe";
        // Set EncyptionAlgorithm
        std.EncryptionAlgorithm = EncryptionAlgorithm.RC4;
        std.EncryptionKeyLength = 128;
        // Set the EncryptHandler property.
        doc.Security.EncryptHandler = std;
        // Render text using DrawString method
        g.DrawString("Welcome to GrapeCity, Inc", new TextFormat()
        { Font = StandardFonts.TimesBold, FontSize = 12 }, new PointF(In, In));
        // Save document
        doc.Save(stream);
    }

GcPdf also supports Standard Security Handler Revision 6 (defined in the PDF 2.0 specification) which uses AES encryption with 256 bit key length.

To encrypt a PDF file using Standard Security Handler Revision 6:

  1. Create an object of StandardSecurityHandlerRev6 class.

  2. Set the required properties of the StandardSecurityHandlerRev6 object, such as password, printing permission, etc.

  3. Pass the object to the EncryptHandler property of the Security class to encrypt the PDF document.

    public void CreatePDF(Stream stream)
    {
        GcPdfDocument doc = new GcPdfDocument();
        var page = doc.NewPage();
        var g = page.Graphics;
        const float In = 150;
        //Add Encryption
        var ssh = new StandardSecurityHandlerRev6();
        ssh.OwnerPassword = "password";
        ssh.PrintingPermissions = PrintingPermissions.Enabled;
        // Set the EncryptHandler property
        doc.Security.EncryptHandler = ssh;
        // Render text using DrawString method
        g.DrawString("Welcome to GrapeCity, Inc", new TextFormat()
        { Font = StandardFonts.TimesBold, FontSize = 12 }, new PointF(In, In));
        // Save document
        doc.Save(stream);
    }

Set Permissions

Setting permissions restricts users from copying, printing and editing the contents in a PDF document. The Security class of the GcPdf library allows a user to set up permissions in a PDF document.

To set permissions in a PDF document:

  1. Create an object of StandardSecurityHandlerRev3 class.

  2. Use the required properties of the StandardSecurityHandlerRev3 object to set the permissions such as editing, printing, etc.

  3. Pass the object to the EncryptHandler property of the Security class.

    public void CreatePDF(Stream stream)
    {
        GcPdfDocument doc = new GcPdfDocument();
        var page = doc.NewPage();
        var g = page.Graphics;
        int In = 72;
    
        // Create a security handler variable
        var std = new StandardSecurityHandlerRev3();
        std.EditingPermissions = EditingPermissions.Enabled;
        std.OwnerPassword = "abc";
        std.UserPassword = "qwe";
    
        // Set permissions
        std.EditingPermissions = EditingPermissions.Enabled;
        std.CopyContentPermissions = CopyContentPermissions.Enabled;
        std.PrintingPermissions = PrintingPermissions.Disabled;
        doc.Security.EncryptHandler = std;
    
        // Render text using DrawString method
        g.DrawString("Welcome to GrapeCity, Inc.", new TextFormat()
        { Font = StandardFonts.TimesBold, FontSize = 12 }, new PointF(In, In));
    
        // Save document
        doc.Save(stream);
    }

Open Encrypted PDF Without Password

Sometimes you might want to load encrypted PDF files without specifying the password. GcPdf allows you to open a password-protected PDF file without specifying the password using Load(Stream stream, DecryptionOptions decryptionOptions) overload of GcPdfDocument class after setting the ThrowExceptionIfInvalidPassword property (flag) of DecryptionOptions class to false (by default, it is true). While there are many limitations to what you can do with a PDF opened in this way, you can:

  • Read and write properties that are not based on PDF strings or streams.

  • Add new objects if they can be defined without using PDF strings or streams.

The PDF format has the "object stream" feature. An object stream is a stream object in which a sequence of indirect objects is stored, rather than at the outermost file level. In the case of encrypted PDF, the object stream is also encrypted so that the PDF objects it contains are not accessible. As a result, GcPdf cannot open the PDF files with the object stream function without knowing the password, and raises an exception. When working with password-protected PDFs without specifying the password, you cannot:

  • Read or write PDF strings.

  • Change the security handler.

  • Read or write properties based on PDF string objects. Typically, those are string properties, such as DocumentInfo.Creator.

  • Read or write stream objects, which means you cannot:

    • Render PDF

    • Add pages with content.

    • Change the content of existing pages.

    • Embed fonts

    • Create or edit annotation appearance streams.

The following sections demonstrate some useful scenarios when working with encrypted PDF files without specifying the password.

Add Annotation

using (FileStream fs = new FileStream("Sample.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    // Initialize GcPdfDocument. 
    GcPdfDocument doc = new GcPdfDocument();

    // Load the PDF file and set the decryption options to false.
    doc.Load(fs, new DecryptionOptions() { ThrowExceptionIfInvalidPassword = false, ThrowExceptionIfUnsupportedSecurityOptions = false });

    // Set first page of PDF file as active page.
    var page = doc.Pages[0];

    // Get page size.
    var pageSize = page.Size;

    // Add square annotation.
    SquareAnnotation sa = new SquareAnnotation();
    sa.Page = page;

    /* Remove the UserName it is initialized by default and will cause an exception
       when the document is saved because strings cannot be encrypted. */
    sa.UserName = null;

    // Add square to the page.
    sa.Rect = new RectangleF(10, 10, pageSize.Width - 20, pageSize.Height - 20);

    // Set color of the square.
    sa.Color = Color.Red;

    // Save the PDF file.
    doc.Save("Annotation.pdf");
}

Get Metadata Values

using (FileStream fs = new FileStream("Sample.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    // Initialize GcPdfDocument.
    GcPdfDocument doc = new GcPdfDocument();

    // Load the PDF file and set the decryption options to false.
    doc.Load(fs, new DecryptionOptions() { ThrowExceptionIfInvalidPassword = false, ThrowExceptionIfUnsupportedSecurityOptions = false });

    // Check if the metadata is encrypted or not, and if not, change the metadata.
    bool encryptMetadata = true;
    if (doc.Security.EncryptHandler is StandardSecurityHandlerRev4 ssh)
        encryptMetadata = ssh.EncryptMetadata;

    if (!encryptMetadata)
    {
        // Metadata is not encrypted.
        Metadata m = doc.Metadata;
        Console.WriteLine("The document has not encrypted metadata:");
        Console.WriteLine($"CreatorTool: {m.CreatorTool}");
        Console.WriteLine($"CreateDate: {m.CreateDate}");
    }
    else
    {
        Console.WriteLine("The document metadata is ENCRYPTED");
    }
}

Change Metadata Values

using (FileStream fs = new FileStream("Sample.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    // Initialize GcPdfDocument.
    GcPdfDocument doc = new GcPdfDocument();

    // Load the PDF file and set the decryption options to false.
    doc.Load(fs, new DecryptionOptions() { ThrowExceptionIfInvalidPassword = false, ThrowExceptionIfUnsupportedSecurityOptions = false });

    // Check if the metadata is encrypted or not, and if not, change the metadata.
    bool encryptMetadata = true;
    if (doc.Security.EncryptHandler is StandardSecurityHandlerRev4 ssh)
        encryptMetadata = ssh.EncryptMetadata;

    if (!encryptMetadata)
    {
        // Metadata is not encrypted.
        Metadata m = doc.Metadata;
        Console.WriteLine("The document has not encrypted metadata:");
        Console.WriteLine($"CreatorTool: {m.CreatorTool}");
        Console.WriteLine($"CreateDate: {m.CreateDate}");

        // Change the creator tool value.
        m.CreatorTool = "New value of CreatorTool";

        doc.Save(@"MetaData.pdf");
    }
    else
    {
        Console.WriteLine("The document metadata is ENCRYPTED");
    }
}

Change Page Order

using (FileStream fs = new FileStream("Sample.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    // Initialize GcPdfDocument.
    GcPdfDocument doc = new GcPdfDocument();

    // Load the PDF file and set the decryption options to false.
    doc.Load(fs, new DecryptionOptions() { ThrowExceptionIfInvalidPassword = false, ThrowExceptionIfUnsupportedSecurityOptions = false });

    // Swap the first and second pages.
    doc.Pages.Swap(0, 1);

    // Save the PDF file.
    doc.Save("PageOrder.pdf");
}

Change Value of CheckBoxField and RadioButtonField

using (FileStream fs = new FileStream("Sample.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    // Initialize GcPdfDocument.
    GcPdfDocument doc = new GcPdfDocument();

    // Load the PDF file and set the decryption options to false.
    doc.Load(fs, new DecryptionOptions() { ThrowExceptionIfInvalidPassword = false, ThrowExceptionIfUnsupportedSecurityOptions = false });

    // Change the value of CheckBoxField.
    var cbf = (CheckBoxField)doc.AcroForm.Fields[0];
    cbf.Checked = true;

    // Change the value of RadioButtonField.
    var rbf = (RadioButtonField)doc.AcroForm.Fields[1];
    var values = rbf.GetCheckedAppearanceStreamNames();
    rbf.Value = values[0];

    // Save the PDF file.
    doc.Save("FieldValue.pdf");
}

Change Values of TextField and CombTextField

using (FileStream fs = new FileStream("Sample.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    // Initialize GcPdfDocument.
    GcPdfDocument doc = new GcPdfDocument();

    // Load the PDF file and set the decryption options to false.
    doc.Load(fs, new DecryptionOptions() { ThrowExceptionIfInvalidPassword = false, ThrowExceptionIfUnsupportedSecurityOptions = false });

    // Change the value of CheckBoxField.
    var tf = (TextField)doc.AcroForm.Fields[2];
    tf.PdfValue = new PdfName("New Value");

    // Change the value of CombTextField.
    var ctf = (CombTextField)doc.AcroForm.Fields[3];
    ctf.PdfValue = new PdfName("NEW");

    // Set the NeedAppearances entry of AcroForm.
    doc.AcroForm.Set(PdfName.Std.NeedAppearances, PdfBool.True);

    // Save the PDF file.
    doc.Save("TextField.pdf");
}

Get Statistics

using (FileStream fs = new FileStream("Sample.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
{
    // Initialize GcPdfDocument.
    GcPdfDocument doc = new GcPdfDocument();

    // Load the PDF file and set the decryption options to false.
    doc.Load(fs, new DecryptionOptions() { ThrowExceptionIfInvalidPassword = false, ThrowExceptionIfUnsupportedSecurityOptions = false });

    // Get the page count and size of the pages.
    Console.WriteLine($"Page count: {doc.Pages.Count}");
    Console.WriteLine();
    foreach (Page page in doc.Pages)
    {
        var sz = page.GetRenderSize();
        Console.WriteLine($"Size of {page.Index} page: {sz.Width}x{sz.Height}");
    }
}

Note: When using GcPdf without a license key, working with a password-protected PDF without specifying the password has many additional limitations (e.g., any attempt to change and save the PDF will fail due to the addition of the license nag text). You can ask for an evaluation license key by sending an email to info.xa@grapecity.com and evaluate the product for 30 days without any limitations.

For more information on applying security using GcPdf, see GcPdf sample browser.