@@ -53,12 +53,12 @@ public class StandardHandlerUsingAes256 extends StandardSecurityHandler {
53
53
private static final int KEY_SALT_OFFSET = 40 ;
54
54
private static final int SALT_LENGTH = 8 ;
55
55
56
- private boolean isPdf2 ;
57
56
protected boolean encryptMetadata ;
58
-
57
+ private boolean isPdf2 ;
59
58
60
59
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 ) {
62
62
isPdf2 = version != null && version .compareTo (PdfVersion .PDF_2_0 ) >= 0 ;
63
63
initKeyAndFillDictionary (encryptionDictionary , userPassword , ownerPassword , permissions , encryptMetadata ,
64
64
embeddedFilesOnly );
@@ -68,6 +68,11 @@ public StandardHandlerUsingAes256(PdfDictionary encryptionDictionary, byte[] pas
68
68
initKeyAndReadDictionary (encryptionDictionary , password );
69
69
}
70
70
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
+ */
71
76
public boolean isEncryptMetadata () {
72
77
return encryptMetadata ;
73
78
}
@@ -87,8 +92,52 @@ public IDecryptor getDecryptor() {
87
92
return new AesDecryptor (nextObjectKey , 0 , nextObjectKeySize );
88
93
}
89
94
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
+
90
139
private void initKeyAndFillDictionary (PdfDictionary encryptionDictionary , byte [] userPassword , byte [] ownerPassword ,
91
- int permissions , boolean encryptMetadata , boolean embeddedFilesOnly ) {
140
+ int permissions , boolean encryptMetadata , boolean embeddedFilesOnly ) {
92
141
ownerPassword = generateOwnerPasswordIfNullOrEmpty (ownerPassword );
93
142
permissions |= PERMS_MASK_1_FOR_REVISION_3_OR_GREATER ;
94
143
permissions &= PERMS_MASK_2 ;
@@ -167,37 +216,6 @@ private void initKeyAndFillDictionary(PdfDictionary encryptionDictionary, byte[]
167
216
}
168
217
}
169
218
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
-
201
219
private void initKeyAndReadDictionary (PdfDictionary encryptionDictionary , byte [] password ) {
202
220
try {
203
221
if (password == null ) {
@@ -206,11 +224,10 @@ private void initKeyAndReadDictionary(PdfDictionary encryptionDictionary, byte[]
206
224
password = Arrays .copyOf (password , 127 );
207
225
}
208
226
209
- isPdf2 = encryptionDictionary .getAsNumber (PdfName .R ).getValue () == 6
210
- || encryptionDictionary .getAsNumber (PdfName .R ).getValue () == 7 ;
227
+ isPdf2 = isPdf2 (encryptionDictionary );
211
228
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
214
231
byte [] oValue = truncateArray (getIsoBytes (encryptionDictionary .getAsString (PdfName .O )));
215
232
byte [] uValue = truncateArray (getIsoBytes (encryptionDictionary .getAsString (PdfName .U )));
216
233
byte [] oeValue = getIsoBytes (encryptionDictionary .getAsString (PdfName .OE ));
@@ -250,7 +267,8 @@ private void initKeyAndReadDictionary(PdfDictionary encryptionDictionary, byte[]
250
267
boolean encryptMetadata = decPerms [8 ] == (byte ) 'T' ;
251
268
252
269
Boolean encryptMetadataEntry = encryptionDictionary .getAsBool (PdfName .EncryptMetadata );
253
- if (permissionsDecoded != permissions || encryptMetadataEntry != null && encryptMetadata != encryptMetadataEntry ) {
270
+ if (permissionsDecoded != permissions || encryptMetadataEntry != null &&
271
+ encryptMetadata != encryptMetadataEntry ) {
254
272
Logger logger = LoggerFactory .getLogger (StandardHandlerUsingAes256 .class );
255
273
logger .error (IoLogMessageConstant .ENCRYPTION_ENTRIES_P_AND_ENCRYPT_METADATA_NOT_CORRESPOND_PERMS_ENTRY );
256
274
}
@@ -263,11 +281,13 @@ private void initKeyAndReadDictionary(PdfDictionary encryptionDictionary, byte[]
263
281
}
264
282
}
265
283
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 {
267
286
return computeHash (password , salt , saltOffset , saltLen , null );
268
287
}
269
288
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 {
271
291
MessageDigest mdSha256 = MessageDigest .getInstance ("SHA-256" );
272
292
273
293
mdSha256 .update (password );
@@ -303,7 +323,8 @@ private byte[] computeHash(byte[] password, byte[] salt, int saltOffset, int sal
303
323
}
304
324
305
325
// 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 ));
307
328
byte [] e = cipher .processBlock (k1 , 0 , k1 .length );
308
329
309
330
// c)
@@ -323,6 +344,7 @@ private byte[] computeHash(byte[] password, byte[] salt, int saltOffset, int sal
323
344
}
324
345
325
346
// d)
347
+ assert md != null ;
326
348
k = md .digest (e );
327
349
328
350
++roundNum ;
0 commit comments