Author: tilman
Date: Tue Mar 24 13:10:57 2026
New Revision: 1932503

Log:
PDFBOX-6181: create SecureRandom only once

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

Modified: 
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java
==============================================================================
--- 
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java
 Tue Mar 24 11:17:54 2026        (r1932502)
+++ 
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/encryption/StandardSecurityHandler.java
 Tue Mar 24 13:10:57 2026        (r1932503)
@@ -27,6 +27,7 @@ import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
 import java.util.Arrays;
+import java.util.Random;
  
 import javax.crypto.Cipher;
 import javax.crypto.spec.IvParameterSpec;
@@ -80,6 +81,9 @@ public final class StandardSecurityHandl
     // hashes used for Algorithm 2.B, depending on remainder from E modulo 3
     private static final String[] HASHES_2B = {"SHA-256", "SHA-384", 
"SHA-512"};
 
+    // SecureRandom.getInstanceStrong() would be better, but sometimes blocks 
on Linux
+    private static final Random RANDOM = new SecureRandom();
+
     /**
      * Constructor.
      */
@@ -426,19 +430,18 @@ public final class StandardSecurityHandl
     {
         try
         {
-            SecureRandom rnd = new SecureRandom();
             Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
 
             // make a random 256-bit file encryption key
             setEncryptionKey(new byte[32]);
-            rnd.nextBytes(getEncryptionKey());
+            RANDOM.nextBytes(getEncryptionKey());
 
             // Algorithm 8a: Compute U
             byte[] userPasswordBytes = 
truncate127(userPassword.getBytes(StandardCharsets.UTF_8));
             byte[] userValidationSalt = new byte[8];
             byte[] userKeySalt = new byte[8];
-            rnd.nextBytes(userValidationSalt);
-            rnd.nextBytes(userKeySalt);
+            RANDOM.nextBytes(userValidationSalt);
+            RANDOM.nextBytes(userKeySalt);
             byte[] hashU = computeHash2B(concat(userPasswordBytes, 
userValidationSalt),
                     userPasswordBytes, null);
             byte[] u = concat(hashU, userValidationSalt, userKeySalt);
@@ -455,8 +458,8 @@ public final class StandardSecurityHandl
             byte[] ownerPasswordBytes = 
truncate127(ownerPassword.getBytes(StandardCharsets.UTF_8));
             byte[] ownerValidationSalt = new byte[8];
             byte[] ownerKeySalt = new byte[8];
-            rnd.nextBytes(ownerValidationSalt);
-            rnd.nextBytes(ownerKeySalt);
+            RANDOM.nextBytes(ownerValidationSalt);
+            RANDOM.nextBytes(ownerKeySalt);
             byte[] hashO = computeHash2B(concat(ownerPasswordBytes, 
ownerValidationSalt, u),
                     ownerPasswordBytes, u);
             byte[] o = concat(hashO, ownerValidationSalt, ownerKeySalt);
@@ -493,7 +496,7 @@ public final class StandardSecurityHandl
             perms[11] = 'b';
             for (int i = 12; i <= 15; i++)
             {
-                perms[i] = (byte) rnd.nextInt();
+                perms[i] = (byte) RANDOM.nextInt();
             }
 
             cipher.init(Cipher.ENCRYPT_MODE, new 
SecretKeySpec(getEncryptionKey(), "AES"),

Reply via email to