您好我正在寻找一个python库,它允许我在一些现有的pdf上设置受密码保护的打印,复制和粘贴选项
我查看了reportlab pdfencrypt模块:这正是我需要的选项,但是开源版本受到严格限制 - 甚至无法设置真实密码,并且许可证不是一个选项(超过1000英镑/年) - 这将是相对较低的数量(每年处理<1000个文档),客户是非营利组织
任何建议非常感谢!
答案 0 :(得分:2)
您(就像我一样)一定想过-WTF是凯文answer的"-3904"
。
请让自己舒服-我有答案)。
我在PDF 1.6参考中找到了它。您可以在这里获取它:https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdf_reference_archive/PDFReference16.pdf
3.5节,页码99:
32位整数,其中包含一组标志,用于指定访问权限 与用户打开文档时应授予权限 访问。表3.20显示了这些标志的含义。钻头位置 标志词中的数字从1(低阶)到32 (高阶)。任何位置的1位使能相应的访问 允许。哪些位有意义,在某些情况下如何 解释,取决于安全处理程序的修订号 (在加密字典的R条目中指定)。
*注意:PDF整数对象在内部以带符号的二进制补码形式表示。由于所有保留的高阶标志位在 加密字典的P值必须为1,即值 必须指定为负整数。例如,假设 安全处理程序的修订版2,值-44允许打印和 复制但不允许修改内容和注释。
所以P
是许可!请检查该文档中的表。 -44
的位表示形式为11010100
。
我这样做是这样的(允许打印和复印,但不允许修改内容和注释):
from hashlib import md5
from PyPDF4 import PdfFileReader, PdfFileWriter
from PyPDF4.generic import NameObject, DictionaryObject, ArrayObject, \
NumberObject, ByteStringObject
from PyPDF4.pdf import _alg33, _alg34, _alg35
from PyPDF4.utils import b_
def encrypt(writer_obj: PdfFileWriter, user_pwd, owner_pwd=None, use_128bit=True):
"""
Encrypt this PDF file with the PDF Standard encryption handler.
:param str user_pwd: The "user password", which allows for opening
and reading the PDF file with the restrictions provided.
:param str owner_pwd: The "owner password", which allows for
opening the PDF files without any restrictions. By default,
the owner password is the same as the user password.
:param bool use_128bit: flag as to whether to use 128bit
encryption. When false, 40bit encryption will be used. By default,
this flag is on.
"""
import time, random
if owner_pwd == None:
owner_pwd = user_pwd
if use_128bit:
V = 2
rev = 3
keylen = int(128 / 8)
else:
V = 1
rev = 2
keylen = int(40 / 8)
# permit copy and printing only:
P = -44
O = ByteStringObject(_alg33(owner_pwd, user_pwd, rev, keylen))
ID_1 = ByteStringObject(md5(b_(repr(time.time()))).digest())
ID_2 = ByteStringObject(md5(b_(repr(random.random()))).digest())
writer_obj._ID = ArrayObject((ID_1, ID_2))
if rev == 2:
U, key = _alg34(user_pwd, O, P, ID_1)
else:
assert rev == 3
U, key = _alg35(user_pwd, rev, keylen, O, P, ID_1, False)
encrypt = DictionaryObject()
encrypt[NameObject("/Filter")] = NameObject("/Standard")
encrypt[NameObject("/V")] = NumberObject(V)
if V == 2:
encrypt[NameObject("/Length")] = NumberObject(keylen * 8)
encrypt[NameObject("/R")] = NumberObject(rev)
encrypt[NameObject("/O")] = ByteStringObject(O)
encrypt[NameObject("/U")] = ByteStringObject(U)
encrypt[NameObject("/P")] = NumberObject(P)
writer_obj._encrypt = writer_obj._addObject(encrypt)
writer_obj._encrypt_key = key
unmeta = PdfFileReader('my_pdf.pdf')
writer = PdfFileWriter()
writer.appendPagesFromReader(unmeta)
encrypt(writer, '1', '123')
with open('my_pdf_encrypted.pdf', 'wb') as fp:
writer.write(fp)
如果您喜欢我的回答,请投票;)。
答案 1 :(得分:1)
PyPDF允许encrypting PDF文件。
答案 2 :(得分:1)
您是否尝试过PDF工具包,命令行界面(pdftk
)?
答案 3 :(得分:1)
Laaate回答,但我想开始做出贡献......
在pdf.py文件中,在encypt()方法中,更改标志:
# permit everything:
P = -1
为:
# prevent everything:
P = -3904
这将阻止除简单查看之外的所有功能。请务必传递不同的所有者密码。