文章目录
最近在讨论PDF报告的需求的时候,提到一块给PDF文件加密以及禁止复制等操作,我们业务开发中是从tcpdf演化到wkhtmltopdf,由于wkhtmltopdf一直停留到0.12.6版本,并且作者已经很久没有更新,扩展加密等操作都没有支持,只能换个思路来完成对PDF的加密操作,原有的逻辑保持不变,额外增加脚本对已经生成好的PDF文件进行再次加密操作。
wkhtmltopdf
本身不支持直接生成带密码的PDF文件(加密功能)。它主要用于将HTML内容转换为PDF,但不具备设置打开密码或权限密码的功能。
但是可以快速开发PDF文档,扩展功能我们就采用另外的工具来达到目的。
以下经过调研总结出3种方法来实现加密(设置密码、禁止打印、禁止修改、禁止复制),以下进行优劣对比:
命令行实现步骤:
使用wkhtmltopdf生成PDF。
使用PDFtk、qpdf、Ghostscript添加密码并限制复制操作。
可选:删除未加密的PDF。脚本化:将命令写入bash脚本以实现自动化。
简要对比
- 首选PDFtk:命令简单,适合快速加密和禁止复制,推荐用于大多数场景。
- 同级首选qpdf:命令简单,速度也快,并且是AES-256的加密方式。
- 备选Ghostscript:当需要AES-256加密或更复杂权限控制时使用。
1、PDFtk
安装pdftk工具(适用于Windows, Mac, Linux)。版本:2.02
使用命令行运行以下命令:
pdftk original.pdf output encrypted.pdf user_pw YOUR_PASSWORD
。这将创建一个名为protected.pdf的新文件,并要求输入指定的密码才能打开。windows测试注意:文件夹权限写入问题。
操作命令:
pdftk
的加密权限通过以下参数控制(需配合user_pw
或owner_pw
使用):allow
:允许的操作(如允许打印、允许复制)。encrypt_128bit
或encrypt_40bit
:加密强度(推荐 128 位)。权限选项
(用空格分隔):
Printing
:允许打印。DegradedPrinting
:允许低质量打印(如屏幕分辨率)。ModifyContents
:允许修改内容(如编辑文本)。Assembly
:允许组装文档(如插入/删除页面)。CopyContents
:允许复制文本/图像。ScreenReaders
:允许屏幕阅读器访问(如文本转语音)。Annotations
:允许添加注释。FillIn
:允许填写表单字段。AllFeatures
:允许所有操作(默认权限)。
关键点:
- 若要 禁止某操作,只需在
allow
中 不包含该权限。 - 必须设置
owner_pw
(所有者密码)才能生效,user_pw
(用户密码)可选。
- 若要 禁止某操作,只需在
#!/bin/bash
# 使用wkhtmltopdf生成PDF
wkhtmltopdf http://example.com input.pdf
# 使用PDFtk为PDF添加密码并禁止复制
pdftk input.pdf output protected.pdf user_pw your_user_password owner_pw your_owner_password allow printing
# 额外操作:禁止复制 + 禁止打印 + 禁止修改
# 仅允许低质量打印、屏幕阅读、填表
pdftk demo.pdf output protected.pdf user_pw 123456 owner_pw 888888 encrypt_128bit allow DegradedPrinting ScreenReaders FillIn
# 完全锁定(禁止所有操作)
pdftk input.pdf output locked.pdf owner_pw 888888 encrypt_128bit allow # 空allow表示禁止所有操作
# 删除原始未加密PDF(可选)
rm input.pdf
# 用 pdftk 查询权限TODO:
pdftk protected.pdf data_dump output permissions.txt
旧版 pdftk
权限语法差异
某些旧版本可能不支持 allow参数,需改用encrypt后直接列权限:
pdftk input.pdf output old_protected.pdf \ owner_pw 888888 \ encrypt_128bit \ user_pw 123456 \ # 旧版可能需通过其他工具(如qpdf)补充权限
2、Ghostscript
比着PDFtk生成时间稍长,版本:10.05
步骤:
通过 Ghostscript 的 -sPDFPassword
参数加密(需 Ghostscript 9.26+)。
安装:
下载 Ghostscript:官网链接
参数:
加密与密码:
-sUserPassword=123456
:用户密码(打开文件时需输入)。-sOwnerPassword=888888
:所有者密码(拥有完全权限,包括修改权限)。-sPDFAES=true
:加密级别,128位AES,默认false是:40位RC4 低安全性,兼容性好 。
权限控制(
-dPermissions
):示例:
- -4 : 禁止打印
- -8:禁止修改文档
- -16:禁止复制内容
- -32:禁止提取内容(类似复制)
- 组合值:权限值可以相加,例如:-dPermissions=-20(-4 -16)表示禁止打印和复制
兼容性:
-dCompatibilityLevel=1.7
确保支持 128 位加密(PDF 1.7 及以上)。- 若需兼容旧版 PDF 阅读器,可降级为
1.4
(但加密强度可能降低)。
#!/bin/bash
# 1、使用wkhtmltopdf生成PDF
wkhtmltopdf http://example.com input.pdf
# 2、禁止修改和复制,但允许打印
gswin64c.exe -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dCompatibilityLevel=1.7 -sOutputFile=protected_print_only.pdf -sUserPassword=123456 -sOwnerPassword=888888 -dPermissions=-40 demo.pdf
# 禁止提取内容-加权限,默认是40位的RC4,当:sPDFAES=true时,128位AES加密
gswin64c.exe -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dCompatibilityLevel=1.7 -sOutputFile=protected_print_only.pdf -sUserPassword=123456 -sOwnerPassword=888888 -dPermissions=-40 -sPDFAES=true demo.pdf
# 3、删除原始未加密PDF(可选)
rm input.pdf
# 4、检查文件是否损坏
gswin64c.exe -dNOPAUSE -dBATCH -sDEVICE=nullpage demo.pdf
替代工具:
若 Ghostscript 权限控制不满足需求,可改用qpdf:
qpdf --encrypt 123456 888888 256 --print=n --copy=n --modify=n -- input.pdf protected.pdf
3、qpdf
速度也挺快,跟pdftk类似,命令行 也简单,版本:12.2.0
步骤:
- 生成 PDF 后,用
qpdf
加密。
安装:
- 大多数系统可通过包管理器安装(如
apt install qpdf
)。
命令:
--print=none
:禁止打印(–print={full,low,none})--modify=none
:禁止修改(–modify={all,annotate,assembly,form,none})--extract=n
:禁止复制或提取文本和图形。(–extract={n,y}),包含:–accessibility=none
示例命令:
# 生成PDF
wkhtmltopdf input.html output.pdf
# 加密(设置用户密码和权限)
qpdf --encrypt USER_PASSWORD OWNER_PASSWORD 256 -- output.pdf encrypted.pdf
# demo 禁止打印、禁止修改
qpdf --encrypt 123456 888888 256 --print=none --modify=none -- demo.pdf encrypted.pdf
# demo 增加额外禁止文本提取
qpdf --encrypt 123456 888888 256 --extract=n --print=none --modify=none -- demo.pdf output.pdf
# 错误1=qpdf: unrecognized argument --copy=none (256-bit encryption options must be terminated with --)
qpdf --encrypt 123456 888888 256 --print=none --modify=none --copy=none -- demo.pdf output.pdf
# 错误1
qpdf --encrypt 123456 888888 256 --allow=print --allow=modify=none --allow=copy=none -- demo.pdf output.pdf
# 错误1
qpdf --encrypt "123456" "888888" 256 --allow=Printing --restrict=Extraction --restrict=Modification -- demo.pdf output.pdf
# 错误1
qpdf --encrypt "123456" "888888" 256 --allow=Feature --restrict=Feature -- demo.pdf output.pdf
# 测试权限:
用 Adobe Acrobat 或 qpdf --show-encryption 检查权限:
qpdf --show-encryption encrypted.pdf
Incorrect password supplied
R = 6
P = -3392
User password =
extract for accessibility: allowed
extract for any purpose: not allowed
print low resolution: not allowed
print high resolution: not allowed
modify document assembly: not allowed
modify forms: not allowed
modify annotations: not allowed
modify other: not allowed
modify anything: not allowed
stream encryption method: AESv3
string encryption method: AESv3
file encryption method: AESv3
4、额外工具
另外还有不需要代码操作的工具
一、桌面端工具(无需编程)
- 福昕PDF编辑器
- 功能:支持 AES-256 加密算法,可设置打开密码和权限密码(禁止编辑、打印、复制)。
- 操作:打开 PDF → 点击【保护】→【安全文档】→ 输入密码并配置权限。
- 优势:专业级加密,支持批量处理,适合企业用户。
- 迅捷PDF转换器(PC版)
- 功能:批量加密 PDF,支持统一密码设置。
- 操作:选择【PDF加密】→ 添加文件 → 输入密码 → 开始加密。
- 优势:界面简洁,支持格式转换、OCR 识别等附加功能。
- Adobe Acrobat Pro
- 功能:行业标准加密工具,支持数字签名和权限管理。
- 操作:打开 PDF → 【文件】→【保护】→【使用密码加密】。
- 优势:与 Adobe 生态无缝集成,适合高端需求。
- WPS
- 功能:支持文档加密、证书加密,可设置编辑页面密码并且加密类型详细:打印、复制、注释、插入和删除页、填写表单和注释。
- 操作:打开WPS→ 【保护】→【文档加密】。
- 优势:常用工具,且免费。
二、在线工具(无需安装)
- PDF24 Tools
- 功能:免费在线加密,支持批量处理和权限控制(如禁止打印)。
- 操作:上传 PDF → 输入密码 → 设置权限 → 下载加密文件。
- 优势:跨平台支持,采用行业标准加密协议。
- SmallPDF
- 功能:一站式 PDF 处理平台,支持加密、解密、转换等。
- 操作:选择【Protect PDF】→ 上传文件 → 设置密码 → 下载。
- 限制:免费版可能限制文件大小或速度。
- 懒人办公官网
- 功能:免费批量加密,支持限制打开、编辑、打印权限。
- 操作:上传文件 → 输入密码 → 批量处理 → 下载。
- 优势:操作简单,适合非技术用户。
三、编程库(自动化流程)
Python + PyPDF2
def add_encryption(input_pdf, output_pdf, password): pdf_writer = PdfFileWriter() pdf_reader = PdfFileReader(input_pdf) for page_num in range(pdf_reader.numPages): pdf_writer.addPage(pdf_reader.getPage(page_num)) pdf_writer.encrypt(user_pwd=password, owner_pwd=None, use_128bit=True) with open(output_pdf, 'wb') as fh: pdf_writer.write(fh) add_encryption(input_pdf='original.pdf', output_pdf='encrypted.pdf', password='your_password')
- 优势:适合嵌入到自动化脚本中,支持灵活定制。
Node.js + pdf-lib
const { PDFDocument } = require('pdf-lib'); const fs = require('fs'); async function encryptPdf() { const pdfBytes = fs.readFileSync('input.pdf'); const pdfDoc = await PDFDocument.load(pdfBytes); pdfDoc.encrypt({ userPassword: 'user_pwd', ownerPassword: 'owner_pwd', permissions: { print: false, modify: false }, }); fs.writeFileSync('encrypted.pdf', await pdfDoc.save()); } encryptPdf();
- 优势:适合 Web 开发或跨平台应用。