empira / PDFsharp

PDFsharp and MigraDoc Foundation for .NET 6 and .NET Framework
https://docs.pdfsharp.net/
Other
398 stars 91 forks source link

Cannot open pdf file when SecuritySettings.OwnerPassword is set #88

Open puwalski opened 4 months ago

puwalski commented 4 months ago

If SecuritySettings.OwnerPassword is set, the document should open without asking for a password, and this is how it worked in version 1.5.x (only setting SecuritySettings.UserPassword protects the document from unauthorised opening). Furthermore, the password set in code is not accepted when opening the file - the file simply cannot be opened. When the same password is set for both SecuritySettings.OwnerPassword and SecuritySettings.UserPassword, the password is also rejected when opening the file.

TH-Soft commented 4 months ago

Did you try with 6.1.0-preview-1?

puwalski commented 4 months ago

I have tried with versions 6.0, 6.1 and 1.5. Only the file created by 1.5 manages to open. I attach the project and the resulting pdfs. PdfSecurityTester.zip test-PdfSharp-6.1.0.0.pdf test-PdfSharp-6.0.0.0.pdf test-PdfSharp-1.50.5147.0.pdf

puwalski commented 4 months ago

The interesting thing is that in the "real" application I'm working on, the save fails at all if I set OwnerPassword. There is one difference though: I am saving to a stream, not to a file. In this case, I get the following exception on line pdfRenderer.PdfDocument.Save(stream, false):

System.InvalidOperationException HResult=0x80131509 Message=Nullable object must have a value. Source=System.Private.CoreLib StackTrace: at System.ThrowHelper.ThrowInvalidOperationException_InvalidOperation_NoValue() at System.Nullable`1.get_Value() at PdfSharp.Pdf.Security.Encryption.PdfEncryptionV1To4.ComputeObjectEncryptionKey(Boolean useAES) at PdfSharp.Pdf.Security.Encryption.PdfEncryptionV1To4.GetObjectEncryptionKeyAES() at PdfSharp.Pdf.Security.Encryption.PdfEncryptionV1To4.EncryptForEnteredObjectUsingAES(Byte[]& bytes) at PdfSharp.Pdf.Security.PdfCryptFilter.EncryptForEnteredObject(Byte[]& bytes) at PdfSharp.Pdf.Security.PdfStandardSecurityHandler.EncryptString(Byte[]& bytes) at PdfSharp.Pdf.Internal.PdfEncoders.FormatStringLiteral(Byte[] bytes, Boolean unicode, Boolean prefix, Boolean hex, PdfStandardSecurityHandler securityHandler) at PdfSharp.Pdf.Internal.PdfEncoders.ToStringLiteral(String text, PdfStringEncoding encoding, PdfStandardSecurityHandler securityHandler) at PdfSharp.Pdf.Annotations.PdfLinkAnnotation.WriteObject(PdfWriter writer) at PdfSharp.Pdf.PdfDocument.DoSave(PdfWriter writer) at PdfSharp.Pdf.PdfDocument.Save(Stream stream, Boolean closeStream) at [...].d__15.MoveNext() in C:[...].cs:line 149

martinossendorf commented 4 months ago

Sorry, I can't reproduce Your issue by now. I'm able to open the files You posted as we'll as files created with Your project using with PDFsharp-MigraDoc 6.0.0 and 6.1.0-preview-1 and a file created with Your project ported back to net472 using PDFsharp-Migradoc 1.50.5147. Using Acrobat Reader 2023, these files open correctly without asking for a password. Did You use another application to open the files? Starting with 6.0.0, PDFsharp by default uses better encryption mechanisms to protect the file. This is PDF encryption version 4 (using AES) with a 128 bit key length. PDFsharp 1.5 used PDF encryption version 2 (RC4) with 128 key length. For the case Your target application does not support newer PDF encryption, You could try inserting the line pdfRenderer.PdfDocument.SecurityHandler.SetEncryptionToV2With128Bits(); before saving the document.

I also couldn't reproduce Your issue with saving the document to a stream. I can add lines in Your test project to save the documents to stream without getting an exception. Anyway, maybe there is a special case not yet considered in PDFsharp, that leads to this exception. Could You provide more of the code creating the document and maybe setting encryption parameters, that runs before saving the document fails?