How to Generate Password Protected PDF in ASP.NET Core MVC

How to Generate Password Protected PDF in ASP.NET Core MVC

In this article, I will discuss How to Generate Password Protected PDF in ASP.NET Core MVC Application with Examples. Please read our previous article discussing How to Generate a PDF in ASP.NET Core MVC Application with Examples. Let’s continue with the application we worked on in previous articles.

How to Generate Password Protected PDF in ASP.NET Core MVC

Generating password-protected PDFs is a wise choice in various scenarios, especially when dealing with sensitive or confidential information. Here are some key situations where you might want to consider this approach:

  • Handling Confidential Documents: If your PDF contains sensitive information like personal data, business secrets, or proprietary information, adding a password is crucial to prevent unauthorized access.
  • Legal and Compliance Requirements: Certain industries are governed by regulations that mandate the protection of client or patient information (like HIPAA in healthcare or GDPR in the European Union). Password-protecting PDFs help in complying with these legal requirements.
  • Financial Documents: For documents such as invoices, bank statements, or financial reports, password protection helps safeguard financial details from unauthorized access or fraud.
  • Business Contracts and Agreements: Contracts often contain proprietary information and legally binding terms. Protecting these documents ensures that only the relevant parties can view or print them.
  • Human Resources Documents: Employee records, payroll information, and performance reviews are typically confidential. Securing these documents protects employee privacy and the company’s internal information.
  • Educational Records: Student records, grades, and other personal information should be secured to maintain privacy and comply with educational privacy laws like FERPA.
  • E-books and Digital Products: For authors and creators, password-protecting PDFs can be a method to protect their intellectual property from unauthorized distribution or piracy.

Let us proceed and see how to generate the Password Protected PDF in the ASP.NET Core Application using the iText Library.

Generate PDF with Password Protection in ASP.NET Core:

Within the PDFService class, add a method to generate a password-protected PDF. So, add the following method within the PDFService class to generate a password-protected PDF. Here, we are hardcoding the password, but in real-time, you need to provide a dynamic password such as date of birth, first name plus year of birth, first and last 4 digits of account number, etc. But, for simplicity, we have hard-coded the user password as Abcd1234 and the owner password as 1234XYZ.

public byte[] GeneratePasswordProtectedPDF(Invoice invoice)
{
    //Generate the PDF
    //Define your memory stream which will temporarily hold the PDF
    using (MemoryStream stream = new MemoryStream())
    {
        // Define writer properties with password protection
        WriterProperties writerProperties = new WriterProperties()
            // Set the user password (needed to open the PDF)
            .SetStandardEncryption(
                userPassword: System.Text.Encoding.UTF8.GetBytes("Abcd1234"),
                ownerPassword: System.Text.Encoding.UTF8.GetBytes("1234XYZ"),
                permissions: EncryptionConstants.ALLOW_PRINTING,
                encryptionAlgorithm: EncryptionConstants.ENCRYPTION_AES_128
            );

        //Initialize PDF writer
        PdfWriter writer = new PdfWriter(stream, writerProperties);

        //Initialize PDF document
        PdfDocument pdf = new PdfDocument(writer);

        // Initialize document
        Document document = new Document(pdf);

        // Add content to the document
        // Header
        document.Add(new Paragraph("Invoice")
            .SetTextAlignment(TextAlignment.CENTER)
            .SetFontSize(20));

        // Invoice data
        document.Add(new Paragraph($"Invoice Number: {invoice.InvoiceNumber}"));
        document.Add(new Paragraph($"Date: {invoice.Date.ToShortDateString()}"));
        document.Add(new Paragraph($"Customer Name: {invoice.CustomerName}"));
        document.Add(new Paragraph($"Payment Mode: {invoice.PaymentMode}"));

        // Table for invoice items
        Table table = new Table(new float[] { 3, 1, 1, 1 });
        table.SetWidth(UnitValue.CreatePercentValue(100));
        table.AddHeaderCell("Iten Name");
        table.AddHeaderCell("Quantity");
        table.AddHeaderCell("Unit Price");
        table.AddHeaderCell("Total");

        foreach (var item in invoice.Items)
        {
            table.AddCell(new Cell().Add(new Paragraph(item.ItemName)));
            table.AddCell(new Cell().Add(new Paragraph(item.Quantity.ToString())));
            table.AddCell(new Cell().Add(new Paragraph(item.UnitPrice.ToString("C"))));
            table.AddCell(new Cell().Add(new Paragraph(item.TotalPrice.ToString("C"))));
        }

        //Add the Table to the PDF Document
        document.Add(table);

        // Total Amount
        document.Add(new Paragraph($"Total Amount: {invoice.TotalAmount.ToString("C")}")
            .SetTextAlignment(TextAlignment.RIGHT));

        // Close the Document
        document.Close();

        return stream.ToArray();
    }
}

User and Owner Password in WriterProperties

In the context of creating or manipulating PDFs in C#, particularly when using libraries like iText or similar, the terms “User Password” and “Owner Password” refer to two different levels of security that can be applied to a PDF document. These are set through WriterProperties or similar configurations. Here’s what each term means:

User Password:
  • The User Password, also known as the document open password, is what users need to enter to open and view the PDF document.
  • If a PDF is secured with a User Password, it cannot be opened and read by anyone who does not have the password.
  • This level of password protection is used when the document creator wants to restrict the access of the document to specific individuals.
Owner Password:
  • The Owner Password, sometimes called the permissions password, allows the setting of various permissions and restrictions on what can be done with the PDF once it’s opened.
  • This might include restrictions on printing, copying text or images, editing, commenting, filling in forms, etc.
  • Users can open and view the document without needing the Owner Password, but they will be restricted from performing certain actions unless they also have this password.
  • The Owner Password is used when the document creator wants to allow people to view the document but restrict certain functionalities.
Create the Password Protected PDF Generation Action Method

Now, we need to call the GeneratePasswordProtectedPDF method in our controller to handle a route that generates the Password Protected PDF. Please add the following action method within the FileUpload Controller. This action method is going to generate and return the Password Protected PDF.

//Generate Password Protected Invoice PDF using iText
public IActionResult GeneratePasswordProtectedInvoicePDF()
{
    // Sample invoice data
    // Here, we have hardcoded the data,
    // In Real-time you will get the data from the database
    var invoice = new Invoice
    {
        InvoiceNumber = "INV-DOTNET-1001",
        Date = DateTime.Now,
        CustomerName = "Pranaya Rout",
        Items = new List<InvoiceItem>
                {
                    new InvoiceItem { ItemName = "Item 1", Quantity = 2, UnitPrice = 15.0m },
                    new InvoiceItem { ItemName = "Item 2", Quantity = 3, UnitPrice = 10.0m },
                    new InvoiceItem { ItemName = "Item 3", Quantity = 1, UnitPrice = 35.0m }
                },
        PaymentMode = "COD"
    };

    //Set the Total Amount
    invoice.TotalAmount = invoice.Items.Sum(x => x.TotalPrice);

    //Create an Instance of PDFService
    PDFService pdfService = new PDFService();

    //Call the GeneratePasswordProtectedPDF method passing the Invoice Data
    var pdfFile = pdfService.GeneratePasswordProtectedPDF(invoice);

    //Return the PDF File
    return File(pdfFile, "application/pdf", "PasswordProtectedInvoice.pdf");
}
Generating the Triggering Action:

Now, let us add a link in the DownloadPDF view to download the Password Protected Invoice PDF. So, modify the DownloadPDF.cshtml view as follows:

@{
    ViewData["Title"] = "DownloadPDF";
}

<h1>Download PDF</h1>
<a href="@Url.Action("GenerateInvoicePDF", "FileUpload")">Download Invoice</a>
<br/>
<h1>Download Password Protected PDF</h1>
<a href="@Url.Action("GeneratePasswordProtectedInvoicePDF", "FileUpload")">Download Password Protected Invoice</a>
Run and Test

Run your application and navigate to the URL FileUpload/DownloadPDF, which should open the following page. Clicking on the Download Password Protected Invoice link, as shown in the image below, triggers the Password Protected PDF generation and download.

How to Generate Password Protected PDF in ASP.NET Core MVC

Once you click on the Download Password Protected Invoice, it will generate and download the Invoice, and when you click on the pdf file, it will ask you to enter the password. To open the PDF file, enter the user password and click on the Submit button, as shown in the image below.

How to Generate Password Protected PDF in ASP.NET Core MVC

Once you enter the user password and click the Submit button, it will open the PDF file, as shown in the image below.

How to Generate Password Protected PDF in ASP.NET Core MVC with Examples

How do you restrict Printing in Password Protected PDFs in C#?

To create a Password Protected PDF and restrict printing in C# using iText, you’ll need to set the appropriate permissions when you apply the password protection. iText allows you to set various permissions, including restricting printing, modifying, and copying of the document.

So, modify the GeneratePasswordProtectedPDF as follows. Here, we are setting the permissions to EncryptionConstants.ALLOW_COPY, which means copying the content of the PDF, is enabled, which also means that printing is disabled for the PDF. Disable means that the user password is disabled, but using the owner password, printing is enabled.

public byte[] GeneratePasswordProtectedPDF(Invoice invoice)
{
    //Generate the PDF
    //Define your memory stream which will temporarily hold the PDF
    using (MemoryStream stream = new MemoryStream())
    {
        // Define writer properties with password protection
        WriterProperties writerProperties = new WriterProperties()
            // Set the user password (needed to open the PDF)
            .SetStandardEncryption(
                userPassword: System.Text.Encoding.UTF8.GetBytes("Abcd1234"),
                ownerPassword: System.Text.Encoding.UTF8.GetBytes("1234XYZ"),
                permissions: EncryptionConstants.ALLOW_COPY,
                encryptionAlgorithm: EncryptionConstants.ENCRYPTION_AES_128
            );

        //Initialize PDF writer
        PdfWriter writer = new PdfWriter(stream, writerProperties);

        //Initialize PDF document
        PdfDocument pdf = new PdfDocument(writer);

        // Initialize document
        Document document = new Document(pdf);

        // Add content to the document
        // Header
        document.Add(new Paragraph("Invoice")
            .SetTextAlignment(TextAlignment.CENTER)
            .SetFontSize(20));

        // Invoice data
        document.Add(new Paragraph($"Invoice Number: {invoice.InvoiceNumber}"));
        document.Add(new Paragraph($"Date: {invoice.Date.ToShortDateString()}"));
        document.Add(new Paragraph($"Customer Name: {invoice.CustomerName}"));
        document.Add(new Paragraph($"Payment Mode: {invoice.PaymentMode}"));

        // Table for invoice items
        Table table = new Table(new float[] { 3, 1, 1, 1 });
        table.SetWidth(UnitValue.CreatePercentValue(100));
        table.AddHeaderCell("Iten Name");
        table.AddHeaderCell("Quantity");
        table.AddHeaderCell("Unit Price");
        table.AddHeaderCell("Total");

        foreach (var item in invoice.Items)
        {
            table.AddCell(new Cell().Add(new Paragraph(item.ItemName)));
            table.AddCell(new Cell().Add(new Paragraph(item.Quantity.ToString())));
            table.AddCell(new Cell().Add(new Paragraph(item.UnitPrice.ToString("C"))));
            table.AddCell(new Cell().Add(new Paragraph(item.TotalPrice.ToString("C"))));
        }

        //Add the Table to the PDF Document
        document.Add(table);

        // Total Amount
        document.Add(new Paragraph($"Total Amount: {invoice.TotalAmount.ToString("C")}")
            .SetTextAlignment(TextAlignment.RIGHT));

        // Close the Document
        document.Close();

        return stream.ToArray();
    }
}

With these changes in place, now run the application and generate and download the PDF. If you open the PDF using a user password, it will only allow you to view the document and copy the content of the PDF, but it will not allow you to print it.

On the other hand, if you open the document using the owner’s password, it will allow you to view it, print it, and copy it. I hope you understand the difference between the User and Owner Password.

Note: If you want to restrict both Coping and Printing, then you need to set the permissions to something else, such as ALLOW_SCREENREADERS, or you can set the value to 0.

How do you apply multiple permissions to A Password-protected PDF in C#?

To apply multiple permissions to a password-protected PDF in C#, we must combine various permission constants from the EncryptionConstants class. We can do this by combining different permission flags with the bitwise OR operator (|). The following example demonstrates how to create a password-protected PDF with multiple restrictions, such as disabling printing and copying.

public byte[] GeneratePasswordProtectedPDF(Invoice invoice)
{
    //Generate the PDF
    //Define your memory stream which will temporarily hold the PDF
    using (MemoryStream stream = new MemoryStream())
    {
        // Define writer properties with password protection
        WriterProperties writerProperties = new WriterProperties()
            // Set the user password (needed to open the PDF)
            .SetStandardEncryption(
                userPassword: System.Text.Encoding.UTF8.GetBytes("Abcd1234"),
                ownerPassword: System.Text.Encoding.UTF8.GetBytes("1234XYZ"),
                permissions: EncryptionConstants.ALLOW_SCREENREADERS |
                             EncryptionConstants.ALLOW_MODIFY_CONTENTS |
                             EncryptionConstants.ALLOW_ASSEMBLY,
                encryptionAlgorithm: EncryptionConstants.ENCRYPTION_AES_128
            );

        //Initialize PDF writer
        PdfWriter writer = new PdfWriter(stream, writerProperties);

        //Initialize PDF document
        PdfDocument pdf = new PdfDocument(writer);

        // Initialize document
        Document document = new Document(pdf);

        // Add content to the document
        // Header
        document.Add(new Paragraph("Invoice")
            .SetTextAlignment(TextAlignment.CENTER)
            .SetFontSize(20));

        // Invoice data
        document.Add(new Paragraph($"Invoice Number: {invoice.InvoiceNumber}"));
        document.Add(new Paragraph($"Date: {invoice.Date.ToShortDateString()}"));
        document.Add(new Paragraph($"Customer Name: {invoice.CustomerName}"));
        document.Add(new Paragraph($"Payment Mode: {invoice.PaymentMode}"));

        // Table for invoice items
        Table table = new Table(new float[] { 3, 1, 1, 1 });
        table.SetWidth(UnitValue.CreatePercentValue(100));
        table.AddHeaderCell("Iten Name");
        table.AddHeaderCell("Quantity");
        table.AddHeaderCell("Unit Price");
        table.AddHeaderCell("Total");

        foreach (var item in invoice.Items)
        {
            table.AddCell(new Cell().Add(new Paragraph(item.ItemName)));
            table.AddCell(new Cell().Add(new Paragraph(item.Quantity.ToString())));
            table.AddCell(new Cell().Add(new Paragraph(item.UnitPrice.ToString("C"))));
            table.AddCell(new Cell().Add(new Paragraph(item.TotalPrice.ToString("C"))));
        }

        //Add the Table to the PDF Document
        document.Add(table);

        // Total Amount
        document.Add(new Paragraph($"Total Amount: {invoice.TotalAmount.ToString("C")}")
            .SetTextAlignment(TextAlignment.RIGHT));

        // Close the Document
        document.Close();

        return stream.ToArray();
    }
}

With these changes, if you open the PDF using the user password, then you will see that both the Print and Copy options are disabled, as shown in the image below.

How do you restrict Printing in Password Protected PDFs in C#?

But there is no restriction for the owner’s password. If you open the document using the owner’s password, then it should allow you to copy and print the PDF document, as shown in the image below.

How do you apply multiple permissions to A Password-protected PDF in C#?

Now, if you want to enable Copy and Print functionality for the User password, then you need to modify the GeneratePasswordProtectedPDF method as follows:

public byte[] GeneratePasswordProtectedPDF(Invoice invoice)
{
    //Generate the PDF
    //Define your memory stream which will temporarily hold the PDF
    using (MemoryStream stream = new MemoryStream())
    {
        // Define writer properties with password protection
        WriterProperties writerProperties = new WriterProperties()
            // Set the user password (needed to open the PDF)
            .SetStandardEncryption(
                userPassword: System.Text.Encoding.UTF8.GetBytes("Abcd1234"),
                ownerPassword: System.Text.Encoding.UTF8.GetBytes("1234XYZ"),
                permissions: EncryptionConstants.ALLOW_COPY |
                             EncryptionConstants.ALLOW_PRINTING,

                encryptionAlgorithm: EncryptionConstants.ENCRYPTION_AES_128
            ); 

        //Initialize PDF writer
        PdfWriter writer = new PdfWriter(stream, writerProperties);

        //Initialize PDF document
        PdfDocument pdf = new PdfDocument(writer);

        // Initialize document
        Document document = new Document(pdf);

        // Add content to the document
        // Header
        document.Add(new Paragraph("Invoice")
            .SetTextAlignment(TextAlignment.CENTER)
            .SetFontSize(20));

        // Invoice data
        document.Add(new Paragraph($"Invoice Number: {invoice.InvoiceNumber}"));
        document.Add(new Paragraph($"Date: {invoice.Date.ToShortDateString()}"));
        document.Add(new Paragraph($"Customer Name: {invoice.CustomerName}"));
        document.Add(new Paragraph($"Payment Mode: {invoice.PaymentMode}"));

        // Table for invoice items
        Table table = new Table(new float[] { 3, 1, 1, 1 });
        table.SetWidth(UnitValue.CreatePercentValue(100));
        table.AddHeaderCell("Iten Name");
        table.AddHeaderCell("Quantity");
        table.AddHeaderCell("Unit Price");
        table.AddHeaderCell("Total");

        foreach (var item in invoice.Items)
        {
            table.AddCell(new Cell().Add(new Paragraph(item.ItemName)));
            table.AddCell(new Cell().Add(new Paragraph(item.Quantity.ToString())));
            table.AddCell(new Cell().Add(new Paragraph(item.UnitPrice.ToString("C"))));
            table.AddCell(new Cell().Add(new Paragraph(item.TotalPrice.ToString("C"))));
        }

        //Add the Table to the PDF Document
        document.Add(table);

        // Total Amount
        document.Add(new Paragraph($"Total Amount: {invoice.TotalAmount.ToString("C")}")
            .SetTextAlignment(TextAlignment.RIGHT));

        // Close the Document
        document.Close();

        return stream.ToArray();
    }
}
How do you exclude the Owner Password in the Password Protected PDF in ASP.NET Core?

If you want to create a Password Protected PDF without an Owner Password, you can pass null or an empty byte array for the owner password in the SetStandardEncryption method. This will apply encryption and restrictions using only the User Password, meaning anyone with the User Password can open the document. Still, there will be no separate owner password to bypass the restrictions. To test the same, please modify the GeneratePasswordProtectedPDF as follows.

public byte[] GeneratePasswordProtectedPDF(Invoice invoice)
{
    //Generate the PDF
    //Define your memory stream which will temporarily hold the PDF
    using (MemoryStream stream = new MemoryStream())
    {
        // Define writer properties with password protection
        WriterProperties writerProperties = new WriterProperties()
            // Set the user password (needed to open the PDF)
            .SetStandardEncryption(
                userPassword: System.Text.Encoding.UTF8.GetBytes("Abcd1234"),
                 null, // No owner password
                permissions: EncryptionConstants.ALLOW_COPY |
                             EncryptionConstants.ALLOW_PRINTING,
                encryptionAlgorithm: EncryptionConstants.ENCRYPTION_AES_128
            );

        //Initialize PDF writer
        PdfWriter writer = new PdfWriter(stream, writerProperties);

        //Initialize PDF document
        PdfDocument pdf = new PdfDocument(writer);

        // Initialize document
        Document document = new Document(pdf);

        // Add content to the document
        // Header
        document.Add(new Paragraph("Invoice")
            .SetTextAlignment(TextAlignment.CENTER)
            .SetFontSize(20));

        // Invoice data
        document.Add(new Paragraph($"Invoice Number: {invoice.InvoiceNumber}"));
        document.Add(new Paragraph($"Date: {invoice.Date.ToShortDateString()}"));
        document.Add(new Paragraph($"Customer Name: {invoice.CustomerName}"));
        document.Add(new Paragraph($"Payment Mode: {invoice.PaymentMode}"));

        // Table for invoice items
        Table table = new Table(new float[] { 3, 1, 1, 1 });
        table.SetWidth(UnitValue.CreatePercentValue(100));
        table.AddHeaderCell("Iten Name");
        table.AddHeaderCell("Quantity");
        table.AddHeaderCell("Unit Price");
        table.AddHeaderCell("Total");

        foreach (var item in invoice.Items)
        {
            table.AddCell(new Cell().Add(new Paragraph(item.ItemName)));
            table.AddCell(new Cell().Add(new Paragraph(item.Quantity.ToString())));
            table.AddCell(new Cell().Add(new Paragraph(item.UnitPrice.ToString("C"))));
            table.AddCell(new Cell().Add(new Paragraph(item.TotalPrice.ToString("C"))));
        }

        //Add the Table to the PDF Document
        document.Add(table);

        // Total Amount
        document.Add(new Paragraph($"Total Amount: {invoice.TotalAmount.ToString("C")}")
            .SetTextAlignment(TextAlignment.RIGHT));

        // Close the Document
        document.Close();

        return stream.ToArray();
    }
}

In the next article, I will discuss HTML to PDF Conversion in ASP.NET Core MVC Applications with examples. In this article, I try to explain How to Generate Password Protected PDF in ASP.NET Core MVC Application with Examples. I hope you enjoy this article on how to generate Password-protected PDFs in ASP.NET Core MVC.

Leave a Reply

Your email address will not be published. Required fields are marked *