如何使用S/MIME证书对PDF文件进行数字签名?

我已经获取了一个由机构颁发的S/MIME证书(一个.p12文件)。在Writer中使用它,我可以按照以下步骤对文档进行数字签名:如何使数字证书可供LibreOffice Writer用于数字签名?

那么,我能用同样的方法对PDF文件进行吗?如果可以,你有什么建议的方法?我希望使用依赖自由软件的解决方案。

13个回答

你唯一的选择是Portable Signer。下载并运行jar文件。但它需要一个p12文件中的私钥(与智能卡不兼容)。
你可能期望Ubuntu的文档签名工具,如qdigidoc或gpg,但不,它们不能用于PDF签名。
你可能会期望Ubuntu的PDF处理工具,如qpdf(提供加密)或pdftk(提供水印),也提供签名功能,但不,它们没有。
可用于你目的的开源工具的完整列表如下: http://wiki.cacert.org/PdfSigning 不幸的是,这些工具目前都没有维护,并且在Ubuntu软件包中找不到。Portable Signer是其中最好维护的工具。
  • Portable Signer自2014年以来没有更新 - 这是所有工具中维护最好的。
  • jSignPdf自2013年以来没有更新。
  • jPdfSign自2006年以来没有更新。
  • CACert的PdfSigner使用过时的iText工具。
  • OpenSignature自2008年以来没有更新。
  • Footprint的链接已损坏。
  • jPDFSecure(商业版)- 2017年更新,但它是一个Java库而不是用户工具。

3截至2020年12月,Portable Signer不再是唯一的选择:KDE的Okular现在可以创建基于证书的嵌入式数字签名,这些签名对其他PDF查看器的用户可见(请参阅我的回答)。 - mak
62022年2月最佳选择:http://jsignpdf.sourceforge.net/ JSignPdf已于2021年12月19日更新,非常易于使用。 - fquinto

好消息!KDE的PDF阅读器Okular(使用Poppler后端)现在支持嵌入式数字签名,类似于Adobe Reader的功能。有关详细信息,请参阅TU Dresden的一篇文章,他们赞助了此功能的实施。
该功能预计将在2021年4月发布的版本中出现(Okular v21.04,Poppler v21.01)。截至2020年12月,已经可以编译当前开发版本的Okular和Poppler PDF库以获取此功能。TU Dresden的文章中提供了说明和构建脚本。

我已按照脚本中的说明完成了安装(在在线预览中要注意被截断的行!)在基于Ubuntu 20.04 LTS的KDE Neon 5.20上使用Poppler(参见Commit 407293bf)和Okular(参见Commit 110ccd61)进行安装(未来版本当然应该继续工作,所以这只是为了完全可重现性)。我已经安装在/usr/local/下,并创建了一个启动脚本okular-sign,其中包含如TU Dresden手册中所定义的变量。新版本的Okular标识为"Version 21.03.70"。正如KDE的典型特点,这个"本地"版本的Okular会与发行版中的官方版本产生冲突,即使在启动旧的二进制文件时也会部分切换到新版本(这可能是由于KDE对"组件"或其他某些组件的系统范围注册)。我希望在我的发行版软件包中发布签名支持后能够恢复到官方版本。

成功安装后,我可以按照帖子中所宣传的创建数字签名的步骤进行操作:
  • 打开一个PDF文件
  • 在“工具”菜单中点击“数字签名”。或者将“数字签名”图标添加到您偏好的工具栏,并点击它。
  • 在您想要显示电子签名可见提示的位置绘制一个矩形。
  • 对话框会询问要使用哪个私钥,如果有多个。选择您想要使用的私钥。
  • 输入您的密钥密码。
之后,系统会提示您将签名后的PDF文件保存为新文件名。

对于这个解决方案点赞。然而,它并没有解决问题。我也尝试过,但问题是无法导入.pfx或.p12文件。或者是我做错了什么? - Stefano_g
1@Stefano_g 我没有在Okular中导入任何证书,但是Okular允许我选择当前的证书进行签名,而无需进一步设置。在Help>Configure Backends>PDF Certificates中,默认的证书数据库是~/.mozilla/firefox下的选项。我之前已经在Firefox中导入了我的证书。 - mak
好的,我只是有点傻。我没有看到导入它的“我的证书”选项卡。我设法签名了,但签名有点丑,就是一个大红色方块。如果我在Windows上操作,得到的结果完全不同,会显示更多的信息。这样正确吗? - Stefano_g
@Stefano_g 是的,PDF中的签名占位符与Adobe产品创建的不同(首先,背景中没有Adobe标志)。我已经不得不向我们管理部门的一些人解释,数字签名的有效性并不取决于这个占位符的外观。这一点被接受了,但我同意一个更加“可信赖”的外观,不要呈现红色(就像无效的签名!)会更好。也许有人可以提出这个问题。 - mak
在我的“工具”菜单中没有“数字签名”选项。 - Mickaël C. Guimarães
我确认了这些困难。目前似乎存在着致命的错误。 - Max Flow
FYI:很快它也应该被添加到Gnome Evince中 https://gitlab.gnome.org/GNOME/evince/-/issues/143 - undefined

如果您在Writer中有可用的证书,并且使用其“导出为PDF”功能,您还可以在导出之前的对话框的最后一个选项卡中对生成的PDF进行数字签名。
据我所知,Android上的Acrobat Reader表示该文档受到保护,这可能会有所帮助。
更新'17:自去年12月以来,您可以通过转到“文件→数字签名→签署现有PDF”来使用LibreOffice签署PDF文件。
这将打开Draw,它能够对PDF进行签名。

3我注意到有时候它无法找到字体,然后整个文档就会变形,将文字推出页面之外。 - Jonathan

我发现你可以使用gpg来对PDF进行签名,以一种仍然可以在查看器中打开的方式。
gpg --clearsign --output=signed.pdf input.pdf

以上将产生一个.asc文件,该文件基本上是输入||签名的串联,但文件扩展名被强制为.pdf,使其在查看器中打开,生成缩略图等。

enter image description here

你可以再次使用gpg验证签名。
$ gpg --verify signed.pdf 
gpg: Podpisano nie, 12 kwi 2015, 19:07:15 CEST z użyciem RSA kluczem
gpg: Poprawny podpis od "Arkadiusz Bulski <arek.bulski@gmail.com>"

请注意,某些pdf文件无法很好地使用此方式进行签署,例如优化的pdf文件。您应该自行检查结果。

3PDF阅读器是否会显示出这是一个PGP签名的PDF文件? - Mendhak
不,尽管附有签名,PDF仍然可以查看。 - ArekBulski
3也许有些软件会忽略GPG头部,但是Adobe Acrobat ReaderFoxit Reader不喜欢它,并认为这样的PDF文件是损坏的。所以确实存在互操作性问题。 - dma_k
4有趣,但问题是关于S/MIME证书的。 - Andy
如何查看这个非分离签名嵌入的PDF文件? - SYK
文件格式已损坏,根据预览应用(Mac)提示。 - f01
3请勿使用--clearsign对PDF文件进行操作。--clearsign只能应用于文本文件,不能应用于其他类型的文件,包括PDF文件。这是因为--clearsign会对文件进行更改,导致失真。参见:https://dev.gnupg.org/T5367 - Hans Deragon

有一个叫做AutoFirma的GPL工具,来自西班牙政府,它与p12格式的证书非常兼容。目前只有西班牙语版本可用,但源代码可以在这里或者Github上找到,并且可以进行翻译。

3需要Java Runtime Environment,但自动依赖安装程序似乎无法解决此问题。请运行以下命令进行安装:sudo apt-get install openjdk-8-jre - Pau Coma Ramirez
这真是一个不错的发现!这个工具非常棒,易于使用,甚至可以插入签名的可视化表示(Herramientas -> Preferencias -> Firma PAdES (PDF) -> 在Opciones de firma下勾选两个框)。 - dav.garcia


谢谢Subv3rsion!另外,在Ubuntu软件中心我也找到了一些专有软件。但是我不打算在这里做广告。 - Agmenor
3好的,但请问你能告诉我你找到了哪些程序吗? - Octávio Filipe Gonçalves
1请注意,GPG和Seahorse可能不支持PDF在商业环境中有时所需的S/MIME格式。 - Thomas Ward
2有时候,有些人确实需要使用.p12文件进行签名。这并没有回答问题。 - jgomo3

我最后做了以下几个步骤:
  1. 安装了Virtual Box
  2. 然后安装了Virtual Box扩展包(用于USB令牌)
  3. 从微软官网免费下载了Windows 10的ISO文件
  4. 启动Windows后,下载了Adobe Reader并签署了文档
虽然这不是最理想的解决方案,但至少完成了工作。

问:我如何在Ubuntu上登录? 答:使用另一个操作系统。 - liakoyras

Master PDF Editor有一个免费版本可以签名.p12文件。
然而,免费版本会留下一个难看的水印。有趣的是,这个水印可以在程序本身或其他PDF编辑器(如LibreOffice Draw)中移除。我认为版本4不会留下水印。

是的,这是唯一有效的解决方案。 - undefined

使用版本大于5.3的LibreOffice,您可以对PDF文档进行签名。 转到文件 > 数字签名 > 签署现有PDF... 原始条目日期为2016年12月: https://vmiklos.hu/blog/pdf-sign.html

这绝对是最简单和最容易的解决方案。它在使用实体令牌时运行良好。 - wazoox

如 @fquinto 在评论中提到: jsignpdf 是一个可靠的选择。
PDF签名软件是用Java编写的。它支持可见签名、时间戳、证书验证和许多其他酷炫功能。