@@ -53,12 +53,12 @@ public class StandardHandlerUsingAes256 extends StandardSecurityHandler {
5353 private static final int KEY_SALT_OFFSET = 40 ;
5454 private static final int SALT_LENGTH = 8 ;
5555
56- private boolean isPdf2 ;
5756 protected boolean encryptMetadata ;
58-
57+ private boolean isPdf2 ;
5958
6059 public StandardHandlerUsingAes256 (PdfDictionary encryptionDictionary , byte [] userPassword , byte [] ownerPassword ,
61- int permissions , boolean encryptMetadata , boolean embeddedFilesOnly , PdfVersion version ) {
60+ int permissions , boolean encryptMetadata , boolean embeddedFilesOnly ,
61+ PdfVersion version ) {
6262 isPdf2 = version != null && version .compareTo (PdfVersion .PDF_2_0 ) >= 0 ;
6363 initKeyAndFillDictionary (encryptionDictionary , userPassword , ownerPassword , permissions , encryptMetadata ,
6464 embeddedFilesOnly );
@@ -68,6 +68,11 @@ public StandardHandlerUsingAes256(PdfDictionary encryptionDictionary, byte[] pas
6868 initKeyAndReadDictionary (encryptionDictionary , password );
6969 }
7070
71+ /**
72+ * Checks whether the document-level metadata stream will be encrypted.
73+ *
74+ * @return {@code true} if the document-level metadata stream shall be encrypted, {@code false} otherwise
75+ */
7176 public boolean isEncryptMetadata () {
7277 return encryptMetadata ;
7378 }
@@ -87,8 +92,52 @@ public IDecryptor getDecryptor() {
8792 return new AesDecryptor (nextObjectKey , 0 , nextObjectKeySize );
8893 }
8994
95+ void setAES256DicEntries (PdfDictionary encryptionDictionary , byte [] oeKey , byte [] ueKey , byte [] aes256Perms ,
96+ boolean encryptMetadata , boolean embeddedFilesOnly ) {
97+ int version = 5 ;
98+ int rAes256 = 5 ;
99+ int rAes256Pdf2 = 6 ;
100+ int revision = isPdf2 ? rAes256Pdf2 : rAes256 ;
101+ PdfName cryptoFilter = PdfName .AESV3 ;
102+ setEncryptionDictionaryEntries (encryptionDictionary , oeKey , ueKey , aes256Perms , encryptMetadata ,
103+ embeddedFilesOnly , version , revision , cryptoFilter );
104+ }
105+
106+ void setEncryptionDictionaryEntries (PdfDictionary encryptionDictionary , byte [] oeKey , byte [] ueKey ,
107+ byte [] aes256Perms , boolean encryptMetadata , boolean embeddedFilesOnly ,
108+ int version , int revision , PdfName cryptoFilter ) {
109+ encryptionDictionary .put (PdfName .OE , new PdfLiteral (StreamUtil .createEscapedString (oeKey )));
110+ encryptionDictionary .put (PdfName .UE , new PdfLiteral (StreamUtil .createEscapedString (ueKey )));
111+ encryptionDictionary .put (PdfName .Perms , new PdfLiteral (StreamUtil .createEscapedString (aes256Perms )));
112+ encryptionDictionary .put (PdfName .R , new PdfNumber (revision ));
113+ encryptionDictionary .put (PdfName .V , new PdfNumber (version ));
114+ PdfDictionary stdcf = new PdfDictionary ();
115+ stdcf .put (PdfName .Length , new PdfNumber (32 ));
116+ if (!encryptMetadata ) {
117+ encryptionDictionary .put (PdfName .EncryptMetadata , PdfBoolean .FALSE );
118+ }
119+ if (embeddedFilesOnly ) {
120+ stdcf .put (PdfName .AuthEvent , PdfName .EFOpen );
121+ encryptionDictionary .put (PdfName .EFF , PdfName .StdCF );
122+ encryptionDictionary .put (PdfName .StrF , PdfName .Identity );
123+ encryptionDictionary .put (PdfName .StmF , PdfName .Identity );
124+ } else {
125+ stdcf .put (PdfName .AuthEvent , PdfName .DocOpen );
126+ encryptionDictionary .put (PdfName .StrF , PdfName .StdCF );
127+ encryptionDictionary .put (PdfName .StmF , PdfName .StdCF );
128+ }
129+ stdcf .put (PdfName .CFM , cryptoFilter );
130+ PdfDictionary cf = new PdfDictionary ();
131+ cf .put (PdfName .StdCF , stdcf );
132+ encryptionDictionary .put (PdfName .CF , cf );
133+ }
134+
135+ boolean isPdf2 (PdfDictionary encryptionDictionary ) {
136+ return encryptionDictionary .getAsNumber (PdfName .R ).getValue () == 6 ;
137+ }
138+
90139 private void initKeyAndFillDictionary (PdfDictionary encryptionDictionary , byte [] userPassword , byte [] ownerPassword ,
91- int permissions , boolean encryptMetadata , boolean embeddedFilesOnly ) {
140+ int permissions , boolean encryptMetadata , boolean embeddedFilesOnly ) {
92141 ownerPassword = generateOwnerPasswordIfNullOrEmpty (ownerPassword );
93142 permissions |= PERMS_MASK_1_FOR_REVISION_3_OR_GREATER ;
94143 permissions &= PERMS_MASK_2 ;
@@ -167,37 +216,6 @@ private void initKeyAndFillDictionary(PdfDictionary encryptionDictionary, byte[]
167216 }
168217 }
169218
170- protected void setAES256DicEntries (PdfDictionary encryptionDictionary , byte [] oeKey , byte [] ueKey , byte [] aes256Perms ,
171- boolean encryptMetadata , boolean embeddedFilesOnly ) {
172- int vAes256 = 5 ;
173- int rAes256 = 5 ;
174- int rAes256Pdf2 = 6 ;
175- encryptionDictionary .put (PdfName .OE , new PdfLiteral (StreamUtil .createEscapedString (oeKey )));
176- encryptionDictionary .put (PdfName .UE , new PdfLiteral (StreamUtil .createEscapedString (ueKey )));
177- encryptionDictionary .put (PdfName .Perms , new PdfLiteral (StreamUtil .createEscapedString (aes256Perms )));
178- encryptionDictionary .put (PdfName .R , new PdfNumber (isPdf2 ? rAes256Pdf2 : rAes256 ));
179- encryptionDictionary .put (PdfName .V , new PdfNumber (vAes256 ));
180- PdfDictionary stdcf = new PdfDictionary ();
181- stdcf .put (PdfName .Length , new PdfNumber (32 ));
182- if (!encryptMetadata ) {
183- encryptionDictionary .put (PdfName .EncryptMetadata , PdfBoolean .FALSE );
184- }
185- if (embeddedFilesOnly ) {
186- stdcf .put (PdfName .AuthEvent , PdfName .EFOpen );
187- encryptionDictionary .put (PdfName .EFF , PdfName .StdCF );
188- encryptionDictionary .put (PdfName .StrF , PdfName .Identity );
189- encryptionDictionary .put (PdfName .StmF , PdfName .Identity );
190- } else {
191- stdcf .put (PdfName .AuthEvent , PdfName .DocOpen );
192- encryptionDictionary .put (PdfName .StrF , PdfName .StdCF );
193- encryptionDictionary .put (PdfName .StmF , PdfName .StdCF );
194- }
195- stdcf .put (PdfName .CFM , PdfName .AESV3 );
196- PdfDictionary cf = new PdfDictionary ();
197- cf .put (PdfName .StdCF , stdcf );
198- encryptionDictionary .put (PdfName .CF , cf );
199- }
200-
201219 private void initKeyAndReadDictionary (PdfDictionary encryptionDictionary , byte [] password ) {
202220 try {
203221 if (password == null ) {
@@ -206,11 +224,10 @@ private void initKeyAndReadDictionary(PdfDictionary encryptionDictionary, byte[]
206224 password = Arrays .copyOf (password , 127 );
207225 }
208226
209- isPdf2 = encryptionDictionary .getAsNumber (PdfName .R ).getValue () == 6
210- || encryptionDictionary .getAsNumber (PdfName .R ).getValue () == 7 ;
227+ isPdf2 = isPdf2 (encryptionDictionary );
211228
212- //truncate user and owner passwords to 48 bytes where the first 32 bytes
213- //are a hash value, next 8 bytes are validation salt and final 8 bytes are the key salt
229+ // Truncate user and owner passwords to 48 bytes where the first 32 bytes
230+ // are a hash value, next 8 bytes are validation salt and final 8 bytes are the key salt
214231 byte [] oValue = truncateArray (getIsoBytes (encryptionDictionary .getAsString (PdfName .O )));
215232 byte [] uValue = truncateArray (getIsoBytes (encryptionDictionary .getAsString (PdfName .U )));
216233 byte [] oeValue = getIsoBytes (encryptionDictionary .getAsString (PdfName .OE ));
@@ -250,7 +267,8 @@ private void initKeyAndReadDictionary(PdfDictionary encryptionDictionary, byte[]
250267 boolean encryptMetadata = decPerms [8 ] == (byte ) 'T' ;
251268
252269 Boolean encryptMetadataEntry = encryptionDictionary .getAsBool (PdfName .EncryptMetadata );
253- if (permissionsDecoded != permissions || encryptMetadataEntry != null && encryptMetadata != encryptMetadataEntry ) {
270+ if (permissionsDecoded != permissions || encryptMetadataEntry != null &&
271+ encryptMetadata != encryptMetadataEntry ) {
254272 Logger logger = LoggerFactory .getLogger (StandardHandlerUsingAes256 .class );
255273 logger .error (IoLogMessageConstant .ENCRYPTION_ENTRIES_P_AND_ENCRYPT_METADATA_NOT_CORRESPOND_PERMS_ENTRY );
256274 }
@@ -263,11 +281,13 @@ private void initKeyAndReadDictionary(PdfDictionary encryptionDictionary, byte[]
263281 }
264282 }
265283
266- private byte [] computeHash (byte [] password , byte [] salt , int saltOffset , int saltLen ) throws NoSuchAlgorithmException {
284+ private byte [] computeHash (byte [] password , byte [] salt , int saltOffset , int saltLen )
285+ throws NoSuchAlgorithmException {
267286 return computeHash (password , salt , saltOffset , saltLen , null );
268287 }
269288
270- private byte [] computeHash (byte [] password , byte [] salt , int saltOffset , int saltLen , byte [] userKey ) throws NoSuchAlgorithmException {
289+ private byte [] computeHash (byte [] password , byte [] salt , int saltOffset , int saltLen , byte [] userKey )
290+ throws NoSuchAlgorithmException {
271291 MessageDigest mdSha256 = MessageDigest .getInstance ("SHA-256" );
272292
273293 mdSha256 .update (password );
@@ -303,7 +323,8 @@ private byte[] computeHash(byte[] password, byte[] salt, int saltOffset, int sal
303323 }
304324
305325 // b)
306- AESCipherCBCnoPad cipher = new AESCipherCBCnoPad (true , Arrays .copyOf (k , 16 ), Arrays .copyOfRange (k , 16 , 32 ));
326+ AESCipherCBCnoPad cipher =
327+ new AESCipherCBCnoPad (true , Arrays .copyOf (k , 16 ), Arrays .copyOfRange (k , 16 , 32 ));
307328 byte [] e = cipher .processBlock (k1 , 0 , k1 .length );
308329
309330 // c)
@@ -323,6 +344,7 @@ private byte[] computeHash(byte[] password, byte[] salt, int saltOffset, int sal
323344 }
324345
325346 // d)
347+ assert md != null ;
326348 k = md .digest (e );
327349
328350 ++roundNum ;
0 commit comments