PDF - 设置受密码保护的打印、复制、粘贴选项?

zac*_*ack 5 python pdf security reportlab

我正在寻找一个 Python 库,它允许我在现有 PDF 文件上设置受密码保护的打印、复制、粘贴选项。

\n

我尝试过的

\n

我查看了reportlab pdfencrypt模块:这正是我需要的选项,但是开源版本受到严格限制 - 甚至无法设置真正的密码,并且许可证不是一个选项(超过\xc2\xa31000/年) - 这个数量相对较低(每年处理< 1000份文档),并且客户是非营利组织

\n

小智 7

你(就像我一样)一定想过 - WTF 来自"-3904"凯文的回答

\n

请让自己舒服 - 我有答案)。

\n

我在 PDF 1.6 参考中找到了它。您可以在这里获取: https: //www.adobe.com/content/dam/acom/en/devnet/pdf/pdf_reference_archive/PDFReference16.pdf

\n

3.5节,第99页:

\n
\n

32 位整数,包含一组标志,指定使用用户访问权限打开文档时应授予的访问权限。表 3.20 显示了这些标志的含义。标志字内的位 posi\xc2\xadtions\n 编号为 1(低位)到 32\n(高位)。任何位置的 1 位都会启用相应的访问权限。哪些位有意义,以及在某些情况下如何解释它们,取决于安全处理程序\xe2\x80\x99s 修订号\n(在加密字典\xe2\x80\x99s R 条目中指定)。

\n

*注意:PDF 整数对象在内部以带符号的二进制补码形式表示。由于要求加密字典\xe2\x80\x99s P val\xc2\xad ue中所有保留的高位标志位都为1,因此该值必须指定为负整数。例如,假设安全处理程序的修订版为 2,则值 -44 允许打印和复制,但不允许修改内容和注释。

\n
\n

所以,P就是许可!请检查该文件中的表格。-44是以11010100位表示的。

\n

我是这样写的(允许打印和复制,但不允许修改内容和注释):

\n
from hashlib import md5\n\nfrom PyPDF4 import PdfFileReader, PdfFileWriter\nfrom PyPDF4.generic import NameObject, DictionaryObject, ArrayObject, \\\n    NumberObject, ByteStringObject\nfrom PyPDF4.pdf import _alg33, _alg34, _alg35\nfrom PyPDF4.utils import b_\n\n\ndef encrypt(writer_obj: PdfFileWriter, user_pwd, owner_pwd=None, use_128bit=True):\n    """\n    Encrypt this PDF file with the PDF Standard encryption handler.\n\n    :param str user_pwd: The "user password", which allows for opening\n        and reading the PDF file with the restrictions provided.\n    :param str owner_pwd: The "owner password", which allows for\n        opening the PDF files without any restrictions.  By default,\n        the owner password is the same as the user password.\n    :param bool use_128bit: flag as to whether to use 128bit\n        encryption.  When false, 40bit encryption will be used.  By default,\n        this flag is on.\n    """\n    import time, random\n    if owner_pwd == None:\n        owner_pwd = user_pwd\n    if use_128bit:\n        V = 2\n        rev = 3\n        keylen = int(128 / 8)\n    else:\n        V = 1\n        rev = 2\n        keylen = int(40 / 8)\n    # permit copy and printing only:\n    P = -44\n    O = ByteStringObject(_alg33(owner_pwd, user_pwd, rev, keylen))\n    ID_1 = ByteStringObject(md5(b_(repr(time.time()))).digest())\n    ID_2 = ByteStringObject(md5(b_(repr(random.random()))).digest())\n    writer_obj._ID = ArrayObject((ID_1, ID_2))\n    if rev == 2:\n        U, key = _alg34(user_pwd, O, P, ID_1)\n    else:\n        assert rev == 3\n        U, key = _alg35(user_pwd, rev, keylen, O, P, ID_1, False)\n    encrypt = DictionaryObject()\n    encrypt[NameObject("/Filter")] = NameObject("/Standard")\n    encrypt[NameObject("/V")] = NumberObject(V)\n    if V == 2:\n        encrypt[NameObject("/Length")] = NumberObject(keylen * 8)\n    encrypt[NameObject("/R")] = NumberObject(rev)\n    encrypt[NameObject("/O")] = ByteStringObject(O)\n    encrypt[NameObject("/U")] = ByteStringObject(U)\n    encrypt[NameObject("/P")] = NumberObject(P)\n    writer_obj._encrypt = writer_obj._addObject(encrypt)\n    writer_obj._encrypt_key = key\n\n\nunmeta = PdfFileReader(\'my_pdf.pdf\')\n\nwriter = PdfFileWriter()\nwriter.appendPagesFromReader(unmeta)\nencrypt(writer, \'1\', \'123\')\n\nwith open(\'my_pdf_encrypted.pdf\', \'wb\') as fp:\n    writer.write(fp)\n
Run Code Online (Sandbox Code Playgroud)\n

如果您喜欢我的回答,请投票;)。

\n


use*_*136 2

您是否尝试过 PDF Toolkit 命令行界面 ( pdftk)?

http://www.pdflabs.com/docs/pdftk-cli-examples/