예제 #1
0
 private void InitKeyAndReadDictionary(PdfDictionary encryptionDictionary, byte[] password)
 {
     try {
         if (password == null)
         {
             password = new byte[0];
         }
         else
         {
             if (password.Length > 127)
             {
                 password = JavaUtil.ArraysCopyOf(password, 127);
             }
         }
         isPdf2 = encryptionDictionary.GetAsNumber(PdfName.R).GetValue() == 6;
         byte[]    oValue  = GetIsoBytes(encryptionDictionary.GetAsString(PdfName.O));
         byte[]    uValue  = GetIsoBytes(encryptionDictionary.GetAsString(PdfName.U));
         byte[]    oeValue = GetIsoBytes(encryptionDictionary.GetAsString(PdfName.OE));
         byte[]    ueValue = GetIsoBytes(encryptionDictionary.GetAsString(PdfName.UE));
         byte[]    perms   = GetIsoBytes(encryptionDictionary.GetAsString(PdfName.Perms));
         PdfNumber pValue  = (PdfNumber)encryptionDictionary.Get(PdfName.P);
         this.permissions = pValue.LongValue();
         byte[] hash;
         hash = ComputeHash(password, oValue, VALIDATION_SALT_OFFSET, SALT_LENGTH, uValue);
         usedOwnerPassword = CompareArray(hash, oValue, 32);
         if (usedOwnerPassword)
         {
             hash = ComputeHash(password, oValue, KEY_SALT_OFFSET, SALT_LENGTH, uValue);
             AESCipherCBCnoPad ac = new AESCipherCBCnoPad(false, hash);
             nextObjectKey = ac.ProcessBlock(oeValue, 0, oeValue.Length);
         }
         else
         {
             hash = ComputeHash(password, uValue, VALIDATION_SALT_OFFSET, SALT_LENGTH);
             if (!CompareArray(hash, uValue, 32))
             {
                 throw new BadPasswordException(PdfException.BadUserPassword);
             }
             hash = ComputeHash(password, uValue, KEY_SALT_OFFSET, SALT_LENGTH);
             AESCipherCBCnoPad ac = new AESCipherCBCnoPad(false, hash);
             nextObjectKey = ac.ProcessBlock(ueValue, 0, ueValue.Length);
         }
         nextObjectKeySize = 32;
         AESCipherCBCnoPad ac_1     = new AESCipherCBCnoPad(false, nextObjectKey);
         byte[]            decPerms = ac_1.ProcessBlock(perms, 0, perms.Length);
         if (decPerms[9] != (byte)'a' || decPerms[10] != (byte)'d' || decPerms[11] != (byte)'b')
         {
             throw new BadPasswordException(PdfException.BadUserPassword);
         }
         int permissionsDecoded = (decPerms[0] & 0xff) | ((decPerms[1] & 0xff) << 8) | ((decPerms[2] & 0xff) << 16)
                                  | ((decPerms[3] & 0xff) << 24);
         bool encryptMetadata      = decPerms[8] == (byte)'T';
         bool?encryptMetadataEntry = encryptionDictionary.GetAsBool(PdfName.EncryptMetadata);
         if (permissionsDecoded != permissions || encryptMetadataEntry != null && encryptMetadata != encryptMetadataEntry
             )
         {
             ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Crypto.Securityhandler.StandardHandlerUsingAes256));
             logger.Error(iText.IO.LogMessageConstant.ENCRYPTION_ENTRIES_P_AND_ENCRYPT_METADATA_NOT_CORRESPOND_PERMS_ENTRY
                          );
         }
         this.permissions     = permissionsDecoded;
         this.encryptMetadata = encryptMetadata;
     }
     catch (BadPasswordException ex) {
         throw;
     }
     catch (Exception ex) {
         throw new PdfException(PdfException.PdfEncryption, ex);
     }
 }