PDF viewer opens but UniPDF says encrypted
A PDF carries two passwords, and they do different jobs.
The user password is what a reader needs to open the file. The owner password restricts operations such as printing, copying text and graphics, modifying the document, and adding or changing notes and AcroForm fields. Those restrictions are honored by convention: they rely on the viewer to respect them, and are not a security control.
UniPDF reports the file as encrypted when either password is set. That is why a document with an owner password but no user password opens without a prompt in a viewer while your code still sees it as encrypted.
Where a user password is set, the correct password is needed to read the file. It 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 usage
- 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
}- 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
}If you are using 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
}