예제 #1
0
        private void PrepareEncryptionDictAES(PdfEncryption encryptionDictionary, PdfName aesVName)
        {
            var cryptFilterDictionary = new PdfCryptFilterDictionary(encryptionDictionary.File);

            cryptFilterDictionary.CryptFilterMethod       = aesVName;
            cryptFilterDictionary.Length                  = keyLength;
            encryptionDictionary.StdCryptFilterDictionary = cryptFilterDictionary;
            encryptionDictionary.StreamFilterName         = PdfName.StdCF;
            encryptionDictionary.StringFilterName         = PdfName.StdCF;
            IsAES = true;
        }
예제 #2
0
        /**
         * Prepare document for encryption.
         *
         * @param document The document to encrypt.
         *
         * @ If there is an error accessing data.
         */
        public override void PrepareDocumentForEncryption(Document document)
        {
            PdfEncryption encryptionDictionary = document.File.Encryption;

            if (encryptionDictionary == null)
            {
                encryptionDictionary = new PdfEncryption(document.File);
            }
            int version  = ComputeVersionNumber();
            int revision = ComputeRevisionNumber(version);

            encryptionDictionary.Filter  = FILTER;
            encryptionDictionary.Version = version;
            if (version != 4 && version != 5)
            {
                // remove CF, StmF, and StrF entries that may be left from a previous encryption
                encryptionDictionary.RemoveV45filters();
            }
            encryptionDictionary.Revision = revision;
            encryptionDictionary.Length   = keyLength;

            string ownerPassword = policy.OwnerPassword ?? string.Empty;
            string userPassword  = policy.UserPassword ?? string.Empty;

            // If no owner password is set, use the user password instead.
            if (ownerPassword.Length == 0)
            {
                ownerPassword = userPassword;
            }

            int permissionInt = policy.Permissions.PermissionBytes;

            encryptionDictionary.Permissions = permissionInt;

            int length = keyLength / 8;

            if (revision == 6)
            {
                // PDFBOX-4155
                ownerPassword = SaslPrep.SaslPrepStored(ownerPassword);
                userPassword  = SaslPrep.SaslPrepStored(userPassword);
                PrepareEncryptionDictRev6(ownerPassword, userPassword, encryptionDictionary, permissionInt);
            }
            else

            {
                PrepareEncryptionDictRev2345(ownerPassword, userPassword, encryptionDictionary, permissionInt,
                                             document, revision, length);
            }

            document.File.Encryption = encryptionDictionary;
        }
예제 #3
0
        private void PrepareEncryptionDictRev2345(string ownerPassword, string userPassword,
                                                  PdfEncryption encryptionDictionary, int permissionInt, Document document,
                                                  int revision, int length)
        {
            var idArray = document.File.ID;

            //check if the document has an id yet.  If it does not then generate one
            if (idArray == null || idArray.BaseDataObject.Count < 2)
            {
                DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                using (var md = MD5.Create())
                {
                    BigInteger time = new BigInteger((DateTime.UtcNow - Jan1st1970).TotalMilliseconds.ToString());
                    md.Update(time.ToByteArray());
                    md.Update(Charset.ISO88591.GetBytes(ownerPassword));
                    md.Update(Charset.ISO88591.GetBytes(userPassword));
                    md.Update(Charset.ISO88591.GetBytes(document.Information.ToString()));

                    var       finBlock = Charset.ISO88591.GetBytes(this.ToString());
                    PdfString idString = new PdfString(md.Digest(finBlock));

                    idArray           = new FileIdentifier();
                    idArray.BaseID    = idString;
                    idArray.VersionID = idString;
                    document.File.ID  = idArray;
                }
            }

            PdfString id = idArray.BaseID;

            byte[] ownerBytes = ComputeOwnerPassword(
                Charset.ISO88591.GetBytes(ownerPassword),
                Charset.ISO88591.GetBytes(userPassword), revision, length);

            byte[] userBytes = ComputeUserPassword(
                Charset.ISO88591.GetBytes(userPassword),
                ownerBytes, permissionInt, id.GetBuffer(), revision, length, true);

            encryptionKey = ComputeEncryptedKey(Charset.ISO88591.GetBytes(userPassword), ownerBytes,
                                                null, null, null, permissionInt, id.GetBuffer(), revision, length, true, false);

            encryptionDictionary.OwnerKey = ownerBytes;
            encryptionDictionary.UserKey  = userBytes;

            if (revision == 4)
            {
                PrepareEncryptionDictAES(encryptionDictionary, PdfName.AESV2);
            }
        }
예제 #4
0
        // Algorithm 13: validate permissions ("Perms" field). Relaxed to accommodate buggy encoders
        // https://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/adobe_supplement_iso32000.pdf
        private void ValidatePerms(PdfEncryption encryption, int dicPermissions, bool encryptMetadata)
        {
            try
            {
                // "Decrypt the 16-byte Perms string using AES-256 in ECB mode with an
                // initialization vector of zero and the file encryption key as the key."
                //@SuppressWarnings({ "squid:S4432"})
                byte[] perms = null;
                using (var cipher = new RijndaelManaged())
                {
                    cipher.Mode    = CipherMode.ECB;
                    cipher.Key     = encryptionKey;
                    cipher.Padding = PaddingMode.None;
                    using (var decriptor = cipher.CreateDecryptor())
                    {
                        perms = decriptor.DoFinal(encryption.Perms);
                    }
                }

                // "Verify that bytes 9-11 of the result are the characters ‘a’, ‘d’, ‘b’."
                if (perms[9] != 'a' || perms[10] != 'd' || perms[11] != 'b')
                {
                    Debug.WriteLine("warn: Verification of permissions failed (constant)");
                }

                // "Bytes 0-3 of the decrypted Perms entry, treated as a little-endian integer,
                // are the user permissions. They should match the value in the P key."
                int permsP = perms[0] & 0xFF | (perms[1] & 0xFF) << 8 | (perms[2] & 0xFF) << 16 |
                             (perms[3] & 0xFF) << 24;

                if (permsP != dicPermissions)
                {
                    Debug.WriteLine($"warn: Verification of permissions failed ({$"{permsP:X8}"} != {$"{dicPermissions:X8}"})");
                }

                if (encryptMetadata && perms[8] != 'T' || !encryptMetadata && perms[8] != 'F')
                {
                    Debug.WriteLine("warn: Verification of permissions failed (EncryptMetadata)");
                }
            }
            catch (Exception e)
            {
                LogIfStrongEncryptionMissing();
                throw new IOException("ValidatePerms", e);
            }
        }
        private void PrepareEncryptionDictAES(PdfEncryption encryptionDictionary, PdfName aesVName, byte[][] recipients)
        {
            PdfCryptFilterDictionary cryptFilterDictionary = new PdfCryptFilterDictionary(encryptionDictionary.File);

            cryptFilterDictionary.CryptFilterMethod = aesVName;
            cryptFilterDictionary.Length            = keyLength;
            PdfArray array = new PdfArray();

            foreach (byte[] recipient in recipients)
            {
                array.Add(new PdfString(recipient));
            }
            cryptFilterDictionary.BaseDataObject[PdfName.Recipients] = array;
            //array.setDirect(true);
            encryptionDictionary.DefaultCryptFilterDictionary = cryptFilterDictionary;
            encryptionDictionary.StreamFilterName             = PdfName.DefaultCryptFilter;
            encryptionDictionary.StringFilterName             = PdfName.DefaultCryptFilter;
            //cryptFilterDictionary.getCOSObject().setDirect(true);
            IsAES = true;
        }
        /**
         * Prepares everything to decrypt the document.
         *
         * @param encryption encryption dictionary, can be retrieved via
         * {@link Document#getEncryption()}
         * @param documentIDArray document id which is returned via
         * {@link org.apache.pdfbox.cos.COSDocument#getDocumentID()} (not used by
         * this handler)
         * @param decryptionMaterial Information used to decrypt the document.
         *
         * @throws IOException If there is an error accessing data. If verbose mode
         * is enabled, the exception message will provide more details why the
         * match wasn't successful.
         */
        public override void PrepareForDecryption(PdfEncryption encryption, PdfArray documentIDArray, DecryptionMaterial decryptionMaterial)
        {
            if (!(decryptionMaterial is PublicKeyDecryptionMaterial))
            {
                throw new IOException(
                          "Provided decryption material is not compatible with the document");
            }

            SetDecryptMetadata(encryption.IsEncryptMetaData);
            if (encryption.Length != 0)
            {
                this.keyLength = encryption.Length;
            }

            PublicKeyDecryptionMaterial material = (PublicKeyDecryptionMaterial)decryptionMaterial;

            try
            {
                bool foundRecipient = false;
                //Org.BouncyCastle.X509.Extension.
                X509Certificate      certificate  = material.Certificate;
                X509CertificateEntry materialCert = null;
                if (certificate != null)
                {
                    materialCert = new X509CertificateEntry(certificate);
                }

                // the decrypted content of the enveloped data that match
                // the certificate in the decryption material provided
                byte[] envelopedData = null;

                // the bytes of each recipient in the recipients array
                PdfArray array = (PdfArray)encryption.BaseDataObject.Resolve(PdfName.Recipients);
                if (array == null)
                {
                    PdfCryptFilterDictionary defaultCryptFilterDictionary = encryption.DefaultCryptFilterDictionary;
                    array = (PdfArray)defaultCryptFilterDictionary.BaseDataObject.Resolve(PdfName.Recipients);
                }
                byte[][] recipientFieldsBytes = new byte[array.Count][];
                //TODO encryption.getRecipientsLength() and getRecipientStringAt() should be deprecated

                int           recipientFieldsLength = 0;
                StringBuilder extraInfo             = new StringBuilder();
                for (int i = 0; i < array.Count; i++)
                {
                    PdfString recipientFieldString = (PdfString)array.Resolve(i);
                    byte[]    recipientBytes       = recipientFieldString.GetBuffer();

                    CmsEnvelopedData data   = new CmsEnvelopedData(recipientBytes);
                    var recipCertificatesIt = data.GetRecipientInfos().GetRecipients();
                    int j = 0;
                    foreach (RecipientInformation ri in recipCertificatesIt)
                    {
                        // Impl: if a matching certificate was previously found it is an error,
                        // here we just don't care about it
                        RecipientID rid = ri.RecipientID;
                        if (!foundRecipient && rid.Match(materialCert))
                        {
                            foundRecipient = true;
                            var privateKey = material.PrivateKey;
                            // might need to call setContentProvider() if we use PKI token, see
                            // http://bouncy-castle.1462172.n4.nabble.com/CMSException-exception-unwrapping-key-key-invalid-unknown-key-type-passed-to-RSA-td4658109.html
                            //DotNetUtilities.GetKeyPair(ri.AlgorithmIdentifier)
                            envelopedData = ri.GetContent(privateKey.Key);
                            break;
                        }
                        j++;
                        if (certificate != null)
                        {
                            extraInfo.Append('\n');
                            extraInfo.Append(j);
                            extraInfo.Append(": ");
                            if (ri is KeyTransRecipientInformation)
                            {
                                appendCertInfo(extraInfo, (KeyTransRecipientInformation)ri, certificate, materialCert);
                            }
                        }
                    }
                    recipientFieldsBytes[i] = recipientBytes;
                    recipientFieldsLength  += recipientBytes.Length;
                }
                if (!foundRecipient || envelopedData == null)
                {
                    throw new IOException("The certificate matches none of " + array.Count
                                          + " recipient entries" + extraInfo.ToString());
                }
                if (envelopedData.Length != 24)
                {
                    throw new IOException("The enveloped data does not contain 24 bytes");
                }
                // now envelopedData contains:
                // - the 20 bytes seed
                // - the 4 bytes of permission for the current user

                byte[] accessBytes = new byte[4];
                Array.Copy(envelopedData, 20, accessBytes, 0, 4);

                AccessPermission currentAccessPermission = new AccessPermission(accessBytes);
                currentAccessPermission.IsReadOnly = true;
                CurrentAccessPermission            = currentAccessPermission;

                // what we will put in the SHA1 = the seed + each byte contained in the recipients array
                byte[] sha1Input = new byte[recipientFieldsLength + 20];

                // put the seed in the sha1 input
                Array.Copy(envelopedData, 0, sha1Input, 0, 20);

                // put each bytes of the recipients array in the sha1 input
                int sha1InputOffset = 20;
                foreach (byte[] recipientFieldsByte in recipientFieldsBytes)
                {
                    Array.Copy(recipientFieldsByte, 0, sha1Input, sha1InputOffset, recipientFieldsByte.Length);
                    sha1InputOffset += recipientFieldsByte.Length;
                }

                byte[] mdResult;
                if (encryption.Version == 4 || encryption.Version == 5)
                {
                    mdResult = SHA256.Create().Digest(sha1Input);

                    // detect whether AES encryption is used. This assumes that the encryption algo is
                    // stored in the PDCryptFilterDictionary
                    // However, crypt filters are used only when V is 4 or 5.
                    PdfCryptFilterDictionary defaultCryptFilterDictionary = encryption.DefaultCryptFilterDictionary;
                    if (defaultCryptFilterDictionary != null)
                    {
                        PdfName cryptFilterMethod = defaultCryptFilterDictionary.CryptFilterMethod;
                        IsAES = PdfName.AESV2.Equals(cryptFilterMethod) || PdfName.AESV3.Equals(cryptFilterMethod);
                    }
                }
                else
                {
                    mdResult = SHA1.Create().Digest(sha1Input);
                }

                // we have the encryption key ...
                encryptionKey = new byte[this.keyLength / 8];
                Array.Copy(mdResult, 0, encryptionKey, 0, this.keyLength / 8);
            }
            catch (Exception e)
            {
                throw new IOException("", e);
            }
        }
        /**
         * Prepare the document for encryption.
         *
         * @param doc The document that will be encrypted.
         *
         * @throws IOException If there is an error while encrypting.
         */
        public override void PrepareDocumentForEncryption(Document doc)
        {
            try
            {
                PdfEncryption dictionary = doc.File.Encryption;
                if (dictionary == null)
                {
                    dictionary = new PdfEncryption(doc.File);
                }

                dictionary.Filter = FILTER;
                dictionary.Length = this.keyLength;
                int version = ComputeVersionNumber();
                dictionary.Version = version;

                // remove CF, StmF, and StrF entries that may be left from a previous encryption
                dictionary.RemoveV45filters();

                // create the 20 bytes seed
                byte[] seed = new byte[20];

                CipherKeyGenerator key;
                try
                {
                    key = GeneratorUtilities.GetKeyGenerator("AES");
                }
                catch (Exception e)
                {
                    // should never happen
                    throw new Exception("AES Key Generator", e);
                }

                key.Init(new KeyGenerationParameters(new SecureRandom(), 192));
                var sk = key.GenerateKey();

                // create the 20 bytes seed
                Array.Copy(sk, 0, seed, 0, 20);

                byte[][] recipientsFields = ComputeRecipientsField(seed);

                int shaInputLength = seed.Length;

                foreach (byte[] field in recipientsFields)
                {
                    shaInputLength += field.Length;
                }

                byte[] shaInput = new byte[shaInputLength];

                Array.Copy(seed, 0, shaInput, 0, 20);

                int shaInputOffset = 20;

                foreach (byte[] recipientsField in recipientsFields)
                {
                    Array.Copy(recipientsField, 0, shaInput, shaInputOffset, recipientsField.Length);
                    shaInputOffset += recipientsField.Length;
                }

                byte[] mdResult;
                if (version == 4 || version == 5)
                {
                    dictionary.SubFilter = SUBFILTER5;
                    mdResult             = SHA256.Create().Digest(shaInput);
                    PdfName aesVName = version == 5 ? PdfName.AESV3 : PdfName.AESV2;
                    PrepareEncryptionDictAES(dictionary, aesVName, recipientsFields);
                }
                else
                {
                    dictionary.SubFilter = SUBFILTER4;
                    mdResult             = SHA1.Create().Digest(shaInput);
                    dictionary.SetRecipients(recipientsFields);
                }

                this.encryptionKey = new byte[this.keyLength / 8];
                Array.Copy(mdResult, 0, this.encryptionKey, 0, this.keyLength / 8);

                doc.File.Encryption = dictionary;
            }
            catch (Exception e)
            {
                throw new IOException("", e);
            }
        }
예제 #8
0
        private void PrepareEncryptionDictRev6(string ownerPassword, string userPassword,
                                               PdfEncryption encryptionDictionary, int permissionInt)
        {
            try
            {
                SecureRandom rnd = new SecureRandom();
                using (var cipher = new RijndaelManaged())
                {
                    cipher.Mode    = CipherMode.CBC;
                    cipher.Padding = PaddingMode.None;
                    // make a random 256-bit file encryption key
                    encryptionKey = new byte[32];
                    rnd.NextBytes(encryptionKey);

                    // Algorithm 8a: Compute U
                    byte[] userPasswordBytes  = Truncate127(Charset.UTF8.GetBytes(userPassword));
                    byte[] userValidationSalt = new byte[8];
                    byte[] userKeySalt        = new byte[8];
                    rnd.NextBytes(userValidationSalt);
                    rnd.NextBytes(userKeySalt);
                    byte[] hashU = ComputeHash2B(Concat(userPasswordBytes, userValidationSalt), userPasswordBytes, null);
                    byte[] u     = Concat(hashU, userValidationSalt, userKeySalt);

                    // Algorithm 8b: Compute UE
                    byte[] hashUE = ComputeHash2B(Concat(userPasswordBytes, userKeySalt), userPasswordBytes, null);
                    byte[] ue     = null;

                    using (var enciptor = cipher.CreateEncryptor(hashUE, new byte[16]))// "an initialization vector of zero"
                    { ue = enciptor.DoFinal(encryptionKey); }

                    // Algorithm 9a: Compute O
                    byte[] ownerPasswordBytes  = Truncate127(Charset.UTF8.GetBytes(ownerPassword));
                    byte[] ownerValidationSalt = new byte[8];
                    byte[] ownerKeySalt        = new byte[8];
                    rnd.NextBytes(ownerValidationSalt);
                    rnd.NextBytes(ownerKeySalt);
                    byte[] hashO = ComputeHash2B(Concat(ownerPasswordBytes, ownerValidationSalt, u), ownerPasswordBytes, u);
                    byte[] o     = Concat(hashO, ownerValidationSalt, ownerKeySalt);

                    // Algorithm 9b: Compute OE
                    byte[] hashOE = ComputeHash2B(Concat(ownerPasswordBytes, ownerKeySalt, u), ownerPasswordBytes, u);
                    byte[] oe     = null;
                    using (var enciptor = cipher.CreateEncryptor(hashOE, new byte[16]))// "an initialization vector of zero"
                    { oe = enciptor.DoFinal(encryptionKey); }

                    // Set keys and other required constants in encryption dictionary
                    encryptionDictionary.UserKey            = u;
                    encryptionDictionary.UserEncryptionKey  = ue;
                    encryptionDictionary.OwnerKey           = o;
                    encryptionDictionary.OwnerEncryptionKey = oe;

                    PrepareEncryptionDictAES(encryptionDictionary, PdfName.AESV3);

                    // Algorithm 10: compute "Perms" value
                    byte[] perms = new byte[16];
                    perms[0]  = (byte)permissionInt;
                    perms[1]  = (byte)((uint)permissionInt >> 8);
                    perms[2]  = (byte)((uint)permissionInt >> 16);
                    perms[3]  = (byte)((uint)permissionInt >> 24);
                    perms[4]  = (byte)0xFF;
                    perms[5]  = (byte)0xFF;
                    perms[6]  = (byte)0xFF;
                    perms[7]  = (byte)0xFF;
                    perms[8]  = (byte)'T';   // we always encrypt Metadata
                    perms[9]  = (byte)'a';
                    perms[10] = (byte)'d';
                    perms[11] = (byte)'b';
                    for (int i = 12; i <= 15; i++)
                    {
                        perms[i] = (byte)rnd.NextInt();
                    }

                    byte[] permsEnc = null;
                    using (var enciptor = cipher.CreateEncryptor(encryptionKey, new byte[16])) // "an initialization vector of zero"
                    { permsEnc = enciptor.DoFinal(perms); }

                    encryptionDictionary.Perms = permsEnc;
                }
            }
            catch (Exception e)
            {
                LogIfStrongEncryptionMissing();
                throw new IOException("PrepareEncryptionDictRev6", e);
            }
        }
예제 #9
0
        /**
         * Prepares everything to decrypt the document.
         *
         * Only if decryption of single objects is needed this should be called.
         *
         * @param encryption  encryption dictionary
         * @param documentIDArray  document id
         * @param decryptionMaterial Information used to decrypt the document.
         *
         * @throws InvalidPasswordException If the password is incorrect.
         * @ If there is an error accessing data.
         */

        public override void PrepareForDecryption(PdfEncryption encryption, PdfArray documentIDArray, DecryptionMaterial decryptionMaterial)
        {
            if (!(decryptionMaterial is StandardDecryptionMaterial))
            {
                throw new IOException("Decryption material is not compatible with the document");
            }

            // This is only used with security version 4 and 5.
            if (encryption.Version >= 4)
            {
                SetStreamFilterName(encryption.StreamFilterName);
                SetStringFilterName(encryption.StreamFilterName);
            }
            SetDecryptMetadata(encryption.IsEncryptMetaData);
            StandardDecryptionMaterial material = (StandardDecryptionMaterial)decryptionMaterial;

            string password = material.Password ?? string.Empty;

            int dicPermissions = encryption.Permissions;
            int dicRevision    = encryption.Revision;
            int dicLength      = encryption.Version == 1 ? 5 : encryption.Length / 8;

            byte[] documentIDBytes = GetDocumentIDBytes(documentIDArray);

            // we need to know whether the meta data was encrypted for password calculation
            bool encryptMetadata = encryption.IsEncryptMetaData;

            byte[] userKey  = encryption.UserKey;
            byte[] ownerKey = encryption.OwnerKey;
            byte[] ue       = null, oe = null;

            var passwordCharset = Charset.ISO88591;

            if (dicRevision == 6 || dicRevision == 5)
            {
                passwordCharset = Charset.UTF8;
                ue = encryption.UserEncryptionKey;
                oe = encryption.OwnerEncryptionKey;
            }

            if (dicRevision == 6)
            {
                password = SaslPrep.SaslPrepQuery(password); // PDFBOX-4155
            }

            AccessPermission currentAccessPermission;

            if (IsOwnerPassword(passwordCharset.GetBytes(password), userKey, ownerKey,
                                dicPermissions, documentIDBytes, dicRevision,
                                dicLength, encryptMetadata))
            {
                currentAccessPermission = AccessPermission.getOwnerAccessPermission();
                CurrentAccessPermission = currentAccessPermission;

                byte[] computedPassword;
                if (dicRevision == 6 || dicRevision == 5)
                {
                    computedPassword = passwordCharset.GetBytes(password);
                }
                else
                {
                    computedPassword = GetUserPassword(passwordCharset.GetBytes(password),
                                                       ownerKey, dicRevision, dicLength);
                }

                encryptionKey =
                    ComputeEncryptedKey(
                        computedPassword,
                        ownerKey, userKey, oe, ue,
                        dicPermissions,
                        documentIDBytes,
                        dicRevision,
                        dicLength,
                        encryptMetadata, true);
            }
            else if (IsUserPassword(passwordCharset.GetBytes(password), userKey, ownerKey,
                                    dicPermissions, documentIDBytes, dicRevision,
                                    dicLength, encryptMetadata))
            {
                currentAccessPermission            = new AccessPermission(dicPermissions);
                currentAccessPermission.IsReadOnly = true;
                CurrentAccessPermission            = currentAccessPermission;

                encryptionKey = ComputeEncryptedKey(
                    passwordCharset.GetBytes(password),
                    ownerKey, userKey, oe, ue,
                    dicPermissions,
                    documentIDBytes,
                    dicRevision,
                    dicLength,
                    encryptMetadata, false);
            }
            else
            {
                throw new InvalidPasswordException("Cannot decrypt PDF, the password is incorrect");
            }

            if (dicRevision == 6 || dicRevision == 5)

            {
                ValidatePerms(encryption, dicPermissions, encryptMetadata);
            }

            if (encryption.Version == 4 || encryption.Version == 5)
            {
                // detect whether AES encryption is used. This assumes that the encryption algo is
                // stored in the PDCryptFilterDictionary
                // However, crypt filters are used only when V is 4 or 5.
                var stdCryptFilterDictionary = encryption.StdCryptFilterDictionary;

                if (stdCryptFilterDictionary != null)
                {
                    PdfName cryptFilterMethod = stdCryptFilterDictionary.CryptFilterMethod;
                    IsAES = PdfName.AESV2.Equals(cryptFilterMethod) ||
                            PdfName.AESV3.Equals(cryptFilterMethod);
                }
            }
        }
예제 #10
0
 /**
  * Prepares everything to decrypt the document.
  *
  * @param encryption  encryption dictionary, can be retrieved via {@link PDDocument#getEncryption()}
  * @param documentIDArray  document id which is returned via {@link org.apache.pdfbox.cos.PdfDocument#getDocumentID()}
  * @param decryptionMaterial Information used to decrypt the document.
  *
  * @throws InvalidPasswordException If the password is incorrect.
  * @throws IOException If there is an error accessing data.
  */
 public abstract void PrepareForDecryption(PdfEncryption encryption, PdfArray documentIDArray, DecryptionMaterial decryptionMaterial);