Author: tilman
Date: Thu Feb 27 05:31:10 2025
New Revision: 1924074
URL: http://svn.apache.org/viewvc?rev=1924074&view=rev
Log:
PDFBOX-5955: pad encryption key as suggested by Ross Johnson; add test
Modified:
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java
pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/encryption/TestSymmetricKeyEncryption.java
Modified:
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java
URL:
http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java?rev=1924074&r1=1924073&r2=1924074&view=diff
==============================================================================
---
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java
(original)
+++
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java
Thu Feb 27 05:31:10 2025
@@ -233,6 +233,9 @@ public final class StandardSecurityHandl
AccessPermission currentAccessPermission;
+ byte[] encryptedKey;
+ byte[] passwordBytes;
+ boolean isOwnerPassword;
if( isOwnerPassword(password.getBytes(passwordCharset), userKey,
ownerKey,
dicPermissions, documentIDBytes, dicRevision,
dicLength, encryptMetadata) )
@@ -240,26 +243,16 @@ public final class StandardSecurityHandl
currentAccessPermission =
AccessPermission.getOwnerAccessPermission();
setCurrentAccessPermission(currentAccessPermission);
- byte[] computedPassword;
if (dicRevision == 6 || dicRevision == 5)
{
- computedPassword = password.getBytes(passwordCharset);
+ passwordBytes = password.getBytes(passwordCharset);
}
else
{
- computedPassword =
getUserPassword(password.getBytes(passwordCharset),
+ passwordBytes =
getUserPassword(password.getBytes(passwordCharset),
ownerKey, dicRevision, dicLength );
}
-
- setEncryptionKey(
- computeEncryptedKey(
- computedPassword,
- ownerKey, userKey, oe, ue,
- dicPermissions,
- documentIDBytes,
- dicRevision,
- dicLength,
- encryptMetadata, true));
+ isOwnerPassword = true;
}
else if( isUserPassword(password.getBytes(passwordCharset), userKey,
ownerKey,
dicPermissions, documentIDBytes, dicRevision,
@@ -268,21 +261,27 @@ public final class StandardSecurityHandl
currentAccessPermission = new AccessPermission(dicPermissions);
currentAccessPermission.setReadOnly();
setCurrentAccessPermission(currentAccessPermission);
-
- setEncryptionKey(
- computeEncryptedKey(
- password.getBytes(passwordCharset),
- ownerKey, userKey, oe, ue,
- dicPermissions,
- documentIDBytes,
- dicRevision,
- dicLength,
- encryptMetadata, false));
+ passwordBytes = password.getBytes(passwordCharset);
+ isOwnerPassword = false;
}
else
{
throw new InvalidPasswordException("Cannot decrypt PDF, the
password is incorrect");
}
+ encryptedKey = computeEncryptedKey(
+ passwordBytes,
+ ownerKey, userKey, oe, ue,
+ dicPermissions,
+ documentIDBytes,
+ dicRevision,
+ dicLength,
+ encryptMetadata, isOwnerPassword);
+ if (dicRevision == 4 && encryptedKey.length < 16)
+ {
+ LOG.info("PDFBOX-5955: padding RC4 key to length 16");
+ encryptedKey = Arrays.copyOf(encryptedKey, 16);
+ }
+ setEncryptionKey(encryptedKey);
if (dicRevision == 6 || dicRevision == 5)
{
Modified:
pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/encryption/TestSymmetricKeyEncryption.java
URL:
http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/encryption/TestSymmetricKeyEncryption.java?rev=1924074&r1=1924073&r2=1924074&view=diff
==============================================================================
---
pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/encryption/TestSymmetricKeyEncryption.java
(original)
+++
pdfbox/branches/2.0/pdfbox/src/test/java/org/apache/pdfbox/encryption/TestSymmetricKeyEncryption.java
Thu Feb 27 05:31:10 2025
@@ -46,6 +46,7 @@ import org.apache.pdfbox.pdmodel.encrypt
import org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler;
import org.apache.pdfbox.pdmodel.graphics.image.ValidateXImage;
import org.apache.pdfbox.rendering.PDFRenderer;
+import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.util.Charsets;
import org.junit.Assert;
@@ -235,6 +236,38 @@ public class TestSymmetricKeyEncryption
}
/**
+ * PDFBOX-5955: test unusual RC4 encryption that has 40 or 48 bits instead
of 128.
+ *
+ * @throws IOException
+ */
+ public void testPDFBox5955() throws IOException
+ {
+ File file40bit = new File("target/pdfs", "PDFBOX-5955-40bit.pdf");
+ File file48bit = new File("target/pdfs", "PDFBOX-5955-48bit.pdf");
+ PDDocument doc = PDDocument.load(file40bit);
+
+ PDFTextStripper stripper = new PDFTextStripper();
+ String text = stripper.getText(doc);
+ assertTrue(text.contains("0x0446615747"));
+ doc.close();
+ doc = PDDocument.load(file40bit);
+ stripper = new PDFTextStripper();
+ text = stripper.getText(doc);
+ assertTrue(text.contains("0x0446615747"));
+ doc.close();
+ doc = PDDocument.load(file48bit);
+ stripper = new PDFTextStripper();
+ text = stripper.getText(doc);
+ assertTrue(text.contains("0x02988E82AFF8"));
+ doc.close();
+ doc = PDDocument.load(file48bit);
+ stripper = new PDFTextStripper();
+ text = stripper.getText(doc);
+ assertTrue(text.contains("0x02988E82AFF8"));
+ doc.close();
+ }
+
+ /**
* Protect a document with an embedded PDF with a key and try to reopen it
* with that key and compare.
*