////////////////////////////////////////////////////////////////////
        // Encryption Constructor
        ////////////////////////////////////////////////////////////////////

        internal PdfEncryption
        (
            PdfDocument Document,
            String UserPassword,
            String OwnerPassword,
            Permission UserPermissions
        ) : base(Document, false)
        {
            // Notes:
            // The PDF File Writer library supports AES 128 encryption only.
            // The library does not strip leading or trailing white space. They are part of the password.
            // EncriptMetadata is assumed to be true (this libraray does not use metadata).
            // Embeded Files Only is assumed to be false (this library does not have embeded files).

            AddToDictionary("/Filter", "/Standard");
            AddToDictionary("/R", "4");
            AddToDictionary("/V", "4");
            AddToDictionary("/Length", "128");

            // remove all unused bits and add all bits that must be one
            Permissions = ((Int32)UserPermissions & (Int32)Permission.All) | PermissionBase;
            AddToDictionary("/P", Permissions.ToString());

            // convert user string password to byte array
            Byte[] UserBinaryPassword = ProcessPassword(UserPassword);

            // convert owner string password to byte array
            if (String.IsNullOrEmpty(OwnerPassword))
            {
                OwnerPassword = BitConverter.ToUInt64(PdfDocument.RandomByteArray(8), 0).ToString();
            }
            Byte[] OwnerBinaryPassword = ProcessPassword(OwnerPassword);

            // calculate owner key for crypto dictionary
            Byte[] OwnerKey = CreateOwnerKey(UserBinaryPassword, OwnerBinaryPassword);

            CreateMasterKey(UserBinaryPassword, OwnerKey);
            Byte[] UserKey = CreateUserKey();

            AddToDictionary("/O", Document.ByteArrayToPdfString(OwnerKey));
            AddToDictionary("/U", Document.ByteArrayToPdfString(UserKey));
            AddToDictionary("/StrF", "/StdCF");
            AddToDictionary("/StmF", "/StdCF");
            AddToDictionary("/CF", "<</StdCF<</Length 16/AuthEvent/DocOpen/CFM/AESV2>>>>");
            return;
        }