If you found this post it most likely means that you're looking for a way to determine if a PDF file is password protected or not using ASP.NET C#. This is a typical requirement of any website accepting user-uploaded files, because those files will probably need to be opened by other users and/or administrators that don't know that password.
Luckily enough I've found a quick and effective way to do that using SyncFusion's PDF libraries, which I've already introduced in this blog a couple years ago. In this post we'll see how we can do that.
The workaround I've used relies upon the PdfLoadedDocument class in the Syncfusion.Pdf.Parsing namespace, which is the standard way used by SyncFusion libraries to read a PDF file in memory. Such class is able to load even password-protected PDF files, as long as we pass the correct password in the constructor; however, if we do instantiate the PDF using the standard "passwordless" overload, it won't be able to do that - thus throwing a Syncfusion.Pdf.PdfDocumentException.
This is precisely what we want! All we need to do is to trap that exception and we're done.
Here's a quick code sample demonstrating such technique:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
foreach (string file in Request.Files) { var errorLst = new List<string>(); HttpPostedFileBase hpfb = Request.Files[file]; var ext = Path.GetExtension(hpfb.FileName).ToLower().Trim('.'); switch (ext) { case "pdf": try { hpfb.InputStream.Position = 0; using (var pdfDoc = new Syncfusion.Pdf.Parsing.PdfLoadedDocument(hpfb.InputStream)) { // do nothing } hpfb.InputStream.Position = 0; } catch (Syncfusion.Pdf.PdfDocumentException pdfE) { // SyncFusion's PDF parser has not been able to read the PDF file: it's probably password protected. errorLst.Add($"File {Path.GetFileName(hpfb.FileName)} seems to be password protected or otherwise unreadable."); } catch (Exception e) { // some other error occurred errorLst.Add($"File {Path.GetFileName(hpfb.FileName)} seems unreadable or invalid."); } } return errorLst; } |
If you need to check for additional layers of protections, such as printing password, you can easily do that using the pdfDoc.Security.Permissions property, which can be checked against the following flags:
- Syncfusion.Pdf.Security.PdfPermissionsFlags.Default : no protection (no passwords)
- Syncfusion.Pdf.Security.PdfPermissionsFlags.AccessibilityCopyContent: copy accessibility content
- Syncfusion.Pdf.Security.PdfPermissionsFlags.AssembleDocument: assemble document permission (only for 128 bits key)
- Syncfusion.Pdf.Security.PdfPermissionsFlags.CopyContent: copy content
- Syncfusion.Pdf.Security.PdfPermissionsFlags.EditAnnotations: add or modify text annotations, fill in interactive form field
- Syncfusion.Pdf.Security.PdfPermissionsFlags.EditContent: edit content
- Syncfusion.Pdf.Security.PdfPermissionsFlags.FillFields: fill form fields (only for 128 bits key)
- Syncfusion.Pdf.Security.PdfPermissionsFlags.FullQualityPrint: full quality print
- Syncfusion.Pdf.Security.PdfPermissionsFlags.Print: print the document
Here's an example of how the above sample can be extended to also check for print-based permissons:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// .. try { hpfb.InputStream.Position = 0; using (var pdfDoc = new Syncfusion.Pdf.Parsing.PdfLoadedDocument(hpfb.InputStream)) { if (pdfDoc.Security.Permissions & (Syncfusion.Pdf.Security.PdfPermissionsFlags.Print | Syncfusion.Pdf.Security.PdfPermissionsFlags.FullQualityprint) != 0) { lstErrors.Add($"File {Path.GetFileName(hpfb.FileName)} is password-protected for printing."); } } hpfb.InputStream.Position = 0; } // .. |
That's it!
Conclusion
I hope that this simple yet effective method will help other ASP.NET developers who are looking for a way to determine if a PDF file is password protected or not.