You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2020/09/17 17:29:18 UTC

svn commit: r1881794 - /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeySecurityHandler.java

Author: tilman
Date: Thu Sep 17 17:29:17 2020
New Revision: 1881794

URL: http://svn.apache.org/viewvc?rev=1881794&view=rev
Log:
PDFBOX-4421: fix bugs to support and enable AES 128 encryption, as suggested by Christian Appl:
- get actual key length from default crypt filter dict (PDFBox was using default 40)
- use SHA1 digest for V 4

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeySecurityHandler.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeySecurityHandler.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeySecurityHandler.java?rev=1881794&r1=1881793&r2=1881794&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeySecurityHandler.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/PublicKeySecurityHandler.java Thu Sep 17 17:29:17 2020
@@ -129,9 +129,14 @@ public final class PublicKeySecurityHand
         }
 
         setDecryptMetadata(encryption.isEncryptMetaData());
-        if (encryption.getLength() != 0)
+        PDCryptFilterDictionary defaultCryptFilterDictionary = encryption.getDefaultCryptFilterDictionary();
+        if (defaultCryptFilterDictionary != null && defaultCryptFilterDictionary.getLength() != 0)
         {
-            this.keyLength = encryption.getLength();
+            setKeyLength(defaultCryptFilterDictionary.getLength());
+        }
+        else if (encryption.getLength() != 0)
+        {
+            setKeyLength(encryption.getLength());
         }
 
         PublicKeyDecryptionMaterial material = (PublicKeyDecryptionMaterial) decryptionMaterial;
@@ -155,7 +160,6 @@ public final class PublicKeySecurityHand
             COSArray array = (COSArray) encryption.getCOSObject().getItem(COSName.RECIPIENTS);
             if (array == null)
             {
-                PDCryptFilterDictionary defaultCryptFilterDictionary = encryption.getDefaultCryptFilterDictionary();
                 array = (COSArray) defaultCryptFilterDictionary.getCOSObject().getItem(COSName.RECIPIENTS);
             }
             byte[][] recipientFieldsBytes = new byte[array.size()][];
@@ -238,12 +242,18 @@ public final class PublicKeySecurityHand
             byte[] mdResult;
             if (encryption.getVersion() == 4 || encryption.getVersion() == 5)
             {
-                mdResult = MessageDigests.getSHA256().digest(sha1Input);
+                if (encryption.getVersion() == 4)
+                {
+                    mdResult = MessageDigests.getSHA1().digest(sha1Input);
+                }
+                else
+                {
+                    mdResult = MessageDigests.getSHA256().digest(sha1Input);
+                }
 
                 // detect whether AES encryption is used. This assumes that the encryption algo is 
                 // stored in the PDCryptFilterDictionary
                 // However, crypt filters are used only when V is 4 or 5.
-                PDCryptFilterDictionary defaultCryptFilterDictionary = encryption.getDefaultCryptFilterDictionary();
                 if (defaultCryptFilterDictionary != null)
                 {
                     COSName cryptFilterMethod = defaultCryptFilterDictionary.getCryptFilterMethod();
@@ -358,12 +368,17 @@ public final class PublicKeySecurityHand
             }
 
             byte[] mdResult;
-            if (version == 4 || version == 5)
+            if (version == 4)
+            {
+                dictionary.setSubFilter(SUBFILTER5);
+                mdResult = MessageDigests.getSHA1().digest(shaInput);
+                prepareEncryptionDictAES(dictionary, COSName.AESV2, recipientsFields);
+            }
+            else if (version == 5)
             {
                 dictionary.setSubFilter(SUBFILTER5);
                 mdResult = MessageDigests.getSHA256().digest(shaInput);
-                COSName aesVName = version == 5 ? COSName.AESV3 : COSName.AESV2;
-                prepareEncryptionDictAES(dictionary, aesVName, recipientsFields);
+                prepareEncryptionDictAES(dictionary, COSName.AESV3, recipientsFields);
             }
             else
             {
@@ -399,8 +414,7 @@ public final class PublicKeySecurityHand
             case 40:
                 return 1;
             case 128:
-                return 2; // prefer RC4 (AES 128 doesn't work yet)
-                //return 4; // prefer AES
+                return 4; // prefer AES
             case 256:
                 return 5;
             default: