Пример #1
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;
        }
Пример #2
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);
                }
            }
        }