Skip to content
PDF viewer opens but UniPDF says encrypted

PDF viewer opens but UniPDF says encrypted

Explanation

There are two ways the security of a pdf file can be protected depending on the type of password provided.

These are:

  • user password: Encrypts the file and prevents opening
  • owner password: which specifies operations that should be restricted even when the document is decrypted, which can include: printing, copying text and graphics out of the document, modifying the document, or adding or modifying text notes and AcroForm fields. The owner password, which controls operations, does not encrypt the file, and instead relies on client software to respect these restrictions, and is not secure.

The UniPDF library detects the file as “encrypted” if the file is protected using either of the above methods.  Here are the possible way you can face this issue.

If the pdf file is encrypted using “user password” then the a correct password is necessary to access the file. In some cases the password can be empty, in which case a standard key is used for decryption. There is no other way around this.

But if it is encrypted using “owner password” then the file can be decrypted and accessed using an empty password. By the way in this case the file can also be viewed using most pdf readers. This means your file falls in this category.

To read and parse a file that is “owner password” protected using UniPDF, it is recommended that you use either NewPdfReaderFromFile or NewPdfReaderWithOpts methods of the model type. 

These two methods try to decrypt the pdf file using an empty password and return a new pdfReader.

Sample usages:

  1. Using model.NewPdfReaderWithOpts method.
func displayNumberOfPages(filePath string) error {
    f, err := os.Open(filePath)
    defer f.Close()
    if err != nil {
        return err
    }

    pdfReader, err := model.NewPdfReaderWithOpts(f, nil)
    if err != nil {
        return err
    }

    numPages, err := pdfReader.GetNumPages()
    if err != nil {
        return err
    }

    fmt.Printf("\n\nThe provided pdf file has %d pages\n", numPages)
    return nil
}
  1. Using model.NewPdfReaderFromFile method.
func printNumberOfPages(filePath string) error {
    pdfReader, f, err := model.NewPdfReaderFromFile(filePath, nil)
    defer f.Close()
    if err != nil {
    return err
    }

    numPages, err := pdfReader.GetNumPages()
    if err != nil {
        return err
    }

    fmt.Printf("\n\nThe provided pdf file has %d pages\n", numPages)
    return nil
}

However if your have decided to use the older model.NewPdfReader method for some reason, then you should first decrypt the file using an empty password as follows.

func printNumberOfPages(filePath string) error {
    f, err := os.Open(filePath)
    defer f.Close()
    if err != nil {
        return err
    }   

    pdfReader, err := model.NewPdfReader(f) 
    isEncrypted, err := pdfReader.IsEncrypted()
    if err != nil {
        return err
    }

    if err != nil {
        return err
    }

    // Try decrypting both with given password(if exists) and an empty one if that fails.   
    password := "" // Using an empty password here.
    if isEncrypted {    
        auth, err := pdfReader.Decrypt([]byte(password))
        fmt.Printf(" -- The pdf file is encrypted!\n")
        if err != nil {
            return err
        }

        if !auth {
            fmt.Printf(" -- the encrpyted file has user password. try providing one \n")
            return err  
        }

        // You can get information on the encryption method if needed.  
        method := pdfReader.GetEncryptionMethod()
        fmt.Printf("-- Encryption Method: %s\n", method)
    }   

    numPages, err := pdfReader.GetNumPages()
    if err != nil {
        return err
    }
    
    fmt.Printf("\n\nThe provided pdf file has %d pages\n", numPages)
    return nil
}