You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2020/05/23 10:17:19 UTC
svn commit: r1878051 - in /pdfbox/branches/2.0:
examples/src/test/java/org/apache/pdfbox/examples/pdmodel/
examples/src/test/resources/org/apache/pdfbox/examples/signature/ pdfbox/
pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/
Author: lehmi
Date: Sat May 23 10:17:19 2020
New Revision: 1878051
URL: http://svn.apache.org/viewvc?rev=1878051&view=rev
Log:
PDFBOX-4784: add optional usage of an external SecureRandom for AES encryption as proposed by Aleksandr Beliakov
Added:
pdfbox/branches/2.0/examples/src/test/resources/org/apache/pdfbox/examples/signature/sign_me_protected.pdf
- copied unchanged from r1878049, pdfbox/trunk/examples/src/test/resources/org/apache/pdfbox/examples/signature/sign_me_protected.pdf
Modified:
pdfbox/branches/2.0/examples/src/test/java/org/apache/pdfbox/examples/pdmodel/TestCreateSignature.java
pdfbox/branches/2.0/pdfbox/ (props changed)
pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandler.java
Modified: pdfbox/branches/2.0/examples/src/test/java/org/apache/pdfbox/examples/pdmodel/TestCreateSignature.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/examples/src/test/java/org/apache/pdfbox/examples/pdmodel/TestCreateSignature.java?rev=1878051&r1=1878050&r2=1878051&view=diff
==============================================================================
--- pdfbox/branches/2.0/examples/src/test/java/org/apache/pdfbox/examples/pdmodel/TestCreateSignature.java (original)
+++ pdfbox/branches/2.0/examples/src/test/java/org/apache/pdfbox/examples/pdmodel/TestCreateSignature.java Sat May 23 10:17:19 2020
@@ -29,12 +29,15 @@ import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.text.MessageFormat;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.Collection;
+import java.util.Date;
import java.util.List;
import org.apache.pdfbox.cos.COSDictionary;
@@ -49,6 +52,7 @@ import org.apache.pdfbox.pdmodel.PDDocum
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.encryption.SecurityProvider;
+import org.apache.pdfbox.pdmodel.interactive.digitalsignature.ExternalSigningSupport;
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.rendering.PDFRenderer;
@@ -65,6 +69,7 @@ import org.bouncycastle.cms.CMSSignedDat
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationVerifier;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
+import org.bouncycastle.crypto.prng.FixedSecureRandom;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.tsp.TSPException;
import org.bouncycastle.tsp.TSPValidationException;
@@ -552,4 +557,67 @@ public class TestCreateSignature
Assert.assertArrayEquals(expectedData.getData(), actualData.getData());
doc.close();
}
-}
\ No newline at end of file
+
+ @Test
+ public void testPDFBox4784() throws Exception
+ {
+
+ Date signingTime = new Date();
+
+ byte[] defaultSignedOne = signEncrypted(null, signingTime);
+ byte[] defaultSignedTwo = signEncrypted(null, signingTime);
+ Assert.assertFalse(Arrays.equals(defaultSignedOne, defaultSignedTwo));
+
+ // a dummy value for FixedSecureRandom is used (for real use-cases a secure value should be provided)
+ byte[] fixedRandomSignedOne = signEncrypted(new FixedSecureRandom(new byte[128]),
+ signingTime);
+ byte[] fixedRandomSignedTwo = signEncrypted(new FixedSecureRandom(new byte[128]),
+ signingTime);
+ Assert.assertTrue(Arrays.equals(fixedRandomSignedOne, fixedRandomSignedTwo));
+
+ }
+
+ private byte[] signEncrypted(SecureRandom secureRandom, Date signingTime) throws Exception
+ {
+ KeyStore keystore = KeyStore.getInstance("PKCS12");
+ keystore.load(new FileInputStream(keystorePath), password.toCharArray());
+
+ CreateSignature signing = new CreateSignature(keystore, password.toCharArray());
+ signing.setExternalSigning(true);
+
+ File inFile = new File(inDir + "sign_me_protected.pdf");
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ PDDocument doc = null;
+ try
+ {
+ doc = PDDocument.load(inFile, " ");
+
+ if (secureRandom != null)
+ {
+ doc.getEncryption().getSecurityHandler().setCustomSecureRandom(secureRandom);
+ }
+
+ PDSignature signature = new PDSignature();
+ signature.setName("Example User");
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(signingTime);
+ signature.setSignDate(cal);
+
+ doc.addSignature(signature);
+ doc.setDocumentId(12345l);
+ ExternalSigningSupport externalSigning = doc.saveIncrementalForExternalSigning(baos);
+ // invoke external signature service
+ byte[] cmsSignature = signing.sign(externalSigning.getContent());
+ // set signature bytes received from the service
+ externalSigning.setSignature(cmsSignature);
+
+ return baos.toByteArray();
+ }
+ finally
+ {
+ IOUtils.closeQuietly(doc);
+ IOUtils.closeQuietly(baos);
+ }
+ }
+}
Propchange: pdfbox/branches/2.0/pdfbox/
------------------------------------------------------------------------------
Merged /pdfbox/trunk/pdfbox:r1878049
Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandler.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandler.java?rev=1878051&r1=1878050&r2=1878051&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandler.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/SecurityHandler.java Sat May 23 10:17:19 2020
@@ -78,6 +78,9 @@ public abstract class SecurityHandler
/** indicates if the Metadata have to be decrypted of not. */
private boolean decryptMetadata;
+ /** Can be used to allow stateless AES encryption */
+ private SecureRandom customSecureRandom;
+
// PDFBOX-4453, PDFBOX-4477: Originally this was just a Set. This failed in rare cases
// when a decrypted string was identical to an encrypted string.
// Because COSString.equals() checks the contents, decryption was then skipped.
@@ -135,6 +138,16 @@ public abstract class SecurityHandler
}
/**
+ * Set the custom SecureRandom.
+ *
+ * @param secureRandom the custom SecureRandom for AES encryption
+ */
+ public void setCustomSecureRandom(SecureRandom customSecureRandom)
+ {
+ this.customSecureRandom = customSecureRandom;
+ }
+
+ /**
* Prepare the document for encryption.
*
* @param doc The document that will be encrypted.
@@ -378,7 +391,7 @@ public abstract class SecurityHandler
else
{
// generate random IV and write to stream
- SecureRandom rnd = new SecureRandom();
+ SecureRandom rnd = getSecureRandom();
rnd.nextBytes(iv);
output.write(iv);
}
@@ -386,9 +399,23 @@ public abstract class SecurityHandler
}
/**
+ * Returns a SecureRandom If customSecureRandom is not defined, instantiate a new SecureRandom
+ *
+ * @return SecureRandom
+ */
+ private SecureRandom getSecureRandom()
+ {
+ if (customSecureRandom != null)
+ {
+ return customSecureRandom;
+ }
+ return new SecureRandom();
+ }
+
+ /**
* This will dispatch to the correct method.
*
- * @param obj The object to decrypt.
+ * @param obj The object to decrypt.
* @param objNum The object number.
* @param genNum The object generation Number.
*