finish support for revision 5 encryption using aes 256 #34

This commit is contained in:
Eliot Jones
2019-06-13 19:46:08 +01:00
parent d0a3cd398f
commit 4c716fcbd6
6 changed files with 52 additions and 35 deletions

View File

@@ -1,39 +1,39 @@
namespace UglyToad.PdfPig.Tests.Integration namespace UglyToad.PdfPig.Tests.Integration
{ {
//using System; using System;
//using System.Diagnostics; using System.Diagnostics;
//using System.IO; using System.IO;
//using Xunit; using Xunit;
/// <summary> /// <summary>
/// A class for testing files which are not checked in to source control. /// A class for testing files which are not checked in to source control.
/// </summary> /// </summary>
public class LocalTests public class LocalTests
{ {
//[Fact] [Fact]
//public void Tests() public void Tests()
//{ {
// var files = Directory.GetFiles(@"C:\temp\pdfs"); var files = Directory.GetFiles(@"C:\temp\pdfs");
// foreach (var file in files) foreach (var file in files)
// { {
// try try
// { {
// using (var document = PdfDocument.Open(file, new ParsingOptions { UseLenientParsing = false })) using (var document = PdfDocument.Open(file, new ParsingOptions { UseLenientParsing = false }))
// { {
// for (var i = 1; i <= document.NumberOfPages; i++) for (var i = 1; i <= document.NumberOfPages; i++)
// { {
// var page = document.GetPage(i); var page = document.GetPage(i);
// var text = page.Text; var text = page.Text;
// Trace.WriteLine(text); Trace.WriteLine(text);
// } }
// } }
// } }
// catch (Exception ex) catch (Exception ex)
// { {
// throw new InvalidOperationException($"Error parsing: {Path.GetFileName(file)}.", ex); throw new InvalidOperationException($"Error parsing: {Path.GetFileName(file)}.", ex);
// } }
// } }
//} }
} }
} }

View File

@@ -45,7 +45,13 @@
/// (PDF 1.6) The application asks the security handler for the encryption key and implicitly decrypts data using the AES algorithm in Cipher Block Chaining (CBC) mode /// (PDF 1.6) The application asks the security handler for the encryption key and implicitly decrypts data using the AES algorithm in Cipher Block Chaining (CBC) mode
/// with a 16-byte block size and an initialization vector that is randomly generated and placed as the first 16 bytes in the stream or string. /// with a 16-byte block size and an initialization vector that is randomly generated and placed as the first 16 bytes in the stream or string.
/// </summary> /// </summary>
AesV2 AesV2,
/// <summary>
/// The application asks the security handler for the encryption key and implicitly decrypts data using the AES-256 algorithm in Cipher Block Chaining (CBC) with padding mode
/// with a 16-byte block size and an initialization vector that is randomly generated and placed as the first 16 bytes in the stream or string.
/// The key size shall be 256 bits.
/// </summary>
AesV3
} }
/// <summary> /// <summary>

View File

@@ -72,6 +72,10 @@
{ {
method = CryptDictionary.Method.AesV2; method = CryptDictionary.Method.AesV2;
} }
else if (cfmName == NameToken.Aesv3)
{
method = CryptDictionary.Method.AesV3;
}
else else
{ {
throw new PdfDocumentEncryptedException($"Unrecognized CFM option for crypt filter {cfm}: {cryptDictionaryToken}."); throw new PdfDocumentEncryptedException($"Unrecognized CFM option for crypt filter {cfm}: {cryptDictionaryToken}.");

View File

@@ -22,8 +22,12 @@
/// </summary> /// </summary>
UnpublishedAlgorithm40To128BitKey = 3, UnpublishedAlgorithm40To128BitKey = 3,
/// <summary> /// <summary>
/// The security handler defines the use of encryption and decryption in the document. /// The security handler defines the use of encryption and decryption in the document with a key length of 128 bits.
/// </summary> /// </summary>
SecurityHandlerInDocument SecurityHandlerInDocument = 4,
/// <summary>
/// The security handler defines the use of encryption and decryption in the document with a key length of 256 bits.
/// </summary>
SecurityHandlerInDocument256 = 5
} }
} }

View File

@@ -75,7 +75,8 @@
{ {
cryptHandler = null; cryptHandler = null;
if (EncryptionAlgorithmCode != EncryptionAlgorithmCode.SecurityHandlerInDocument) if (EncryptionAlgorithmCode != EncryptionAlgorithmCode.SecurityHandlerInDocument
&& EncryptionAlgorithmCode != EncryptionAlgorithmCode.SecurityHandlerInDocument256)
{ {
return false; return false;
} }

View File

@@ -55,7 +55,8 @@
useAes = false; useAes = false;
if (encryptionDictionary.EncryptionAlgorithmCode == EncryptionAlgorithmCode.SecurityHandlerInDocument) if (encryptionDictionary.EncryptionAlgorithmCode == EncryptionAlgorithmCode.SecurityHandlerInDocument
|| encryptionDictionary.EncryptionAlgorithmCode == EncryptionAlgorithmCode.SecurityHandlerInDocument256)
{ {
if (!encryptionDictionary.TryGetCryptHandler(out var cryptHandlerLocal)) if (!encryptionDictionary.TryGetCryptHandler(out var cryptHandlerLocal))
{ {
@@ -64,7 +65,8 @@
cryptHandler = cryptHandlerLocal; cryptHandler = cryptHandlerLocal;
useAes = cryptHandlerLocal?.StreamDictionary?.Name == CryptDictionary.Method.AesV2; useAes = cryptHandlerLocal?.StreamDictionary?.Name == CryptDictionary.Method.AesV2
|| cryptHandlerLocal?.StreamDictionary?.Name == CryptDictionary.Method.AesV3;
} }
var charset = OtherEncodings.Iso88591; var charset = OtherEncodings.Iso88591;
@@ -407,7 +409,7 @@
{ {
if (useAes && encryptionKey.Length == 32) if (useAes && encryptionKey.Length == 32)
{ {
throw new PdfDocumentEncryptedException("Decryption for AES-256 not currently supported.", encryptionDictionary); return AesEncryptionHelper.Decrypt(data, encryptionKey);
} }
var finalKey = GetObjectKey(reference); var finalKey = GetObjectKey(reference);