-
Notifications
You must be signed in to change notification settings - Fork 160
Bug fix for encryption with .NET Framework
There is a bug affecting PDFsharp 6.2.0 Preview 2 and Preview 3, that prevents PDFsharp using .NET Framework 4.6.2 from creating correct encrypted files. When using .NET 6 or higher, the encrypted files are correct.
Bug will be fixed with PDFsharp 6.2.0 final version.
If you need a quick fix, download the source from the repository, apply the fix described here, and compile your own DLLs.
Problem description:
.NET 6 and higher re-initalize the HashAlgorithm
instance after executing TransformFinalBlock
, but .NET 4.6.2 does not.
Fix is calling Initialize
manually after calling TransformFinalBlock
.
Open the file "PdfEncryptionV1To4.cs", locate method "void ComputeAndStoreEncryptionKey(byte[] documentId, byte[] paddedPassword, byte[] ownerValue, uint permissions)".
void ComputeAndStoreEncryptionKey(byte[] documentId, byte[] paddedPassword, byte[] ownerValue, uint permissions)
{
_md5.Initialize();
// Skipped code.
if (RevisionValue >= 4 && !EncryptMetadata)
{
var additionalBytes = new Byte[] { 0xFF, 0xFF, 0xFF, 0xFF };
_md5.TransformBlock(additionalBytes, 0, additionalBytes.Length, additionalBytes, 0);
}
// Finalize Hash by calling TransformFinalBlock() with an input count of 0.
_md5.TransformFinalBlock(permission, 0, 0);
var hash = _md5.Hash!;
int keyLength;
if (RevisionValue >= 3)
{
// The encryption and MD5 hashing key length (in bytes) shall depend on the Length value (in bits).
keyLength = ActualLength!.Value / 8;
// *** Begin of new code. ***
#if !NET6_0_OR_GREATER
// We have to call Initialize here for .NET 4.6.2.
// .NET 6/8 include Initialize in "_md5.TransformFinalBlock()".
_md5.Initialize();
#endif
// *** End of new code. ***
// Create the hash 50 times (only for 128 bit).
for (var idx = 0; idx < 50; idx++)
{
// Only use hash with a length of keyLength.
hash = _md5.ComputeHash(hash, 0, keyLength);
}
}
else
{
// The encryption key length for revision 2 shall be 5.
keyLength = 5;
}
// Skipped code.
}