13

随着 WebCrypto API 的发展和 Chrome 和 Firefox 的支持,我想用它来对 PDF 文档进行数字签名。周围的文献不多,但我找到了一些示例 [1] 和一个名为 PKI.js [2] 的库。在示例中,描述了签名过程,但最终返回了签名。我希望我的 Base64 PDF 文件以签名的 Base64 字符串再次返回,但遗憾的是,这不是发生的情况。据我所知,PKI.js 也没有提供对我的 Base64 PDF 进行签名的方法。

有没有办法仅使用 JavaScript 和 WebCrypto API 签署 PDF?可以将私钥输入<textarea>到浏览器的证书设置中,或者更好地存储在证书设置中。

Base64 PDF(来自 REST API)→ 使用 JS 和证书签名 → 签名的 Base64 PDF(发送到 REST)

4

4 回答 4

7

这在技术上是可行的,事实上这是我们在制作 PKIjs 时想到的场景之一(这就是为什么有这个示例) - https://pkijs.org/examples/PDFexample.html

据说进行签名需要使用 PDF 结构本身,这需要自定义解析器或修改现有解析器(例如 pdfjs)。

长话短说,在浏览器中签署 PDF 需要做很多工作,不过这是我们正在做的事情。

于 2015-10-20T05:24:59.520 回答
4

披露:我为 CISPL 工作。

截至目前,WebCrypto API 不提供对 (Windows) 或任何其他密钥存储或本地加密 USB/智能卡设备的访问。

同样在大多数签名场景中,为了在服务器边界内保护 pdf 文件,不建议将完整的 pdf 文件发送到浏览器或签名 API 服务器。

因此,它的良好做法是创建 PDF 的哈希以进行签名,将哈希发送到浏览器并通过浏览器扩展使用 javascript 访问本地系统上运行的某些应用程序以访问本地密钥库(或 USB/智能卡)并生成签名并发送回( PKCS7 或 CMS 容器(在 PDF 签名的情况下)到服务器,在该服务器中签名可以被注入到 PDF 中,从该 PDF 中创建用于签名的哈希并发送到浏览器或签名 api 服务器。

对于基于浏览器的签名场景,我公司提供了一个这样的免费浏览器扩展 Signer.Digital 和服务器所需的 .NET 库。可以从cNET 下载站点下载本地系统(在 windows 上的 chrome 浏览器后面运行的主机) 安装此主机并重新启动 Chrome 将自动添加Signer.Digital Chrome Extension和/或Signer.Digital Firefox Extension

此处说明了此扩展的实际工作以及完整的代码演练和工作示例 VS 2015 项目源代码的下载链接。

Javascript 从扩展调用方法:

 //Calculate Sign for the Hash by Calling function from Extension SignerDigital
 SignerDigital.signPdfHash(hash, $("#CertThumbPrint").val(), "SHA-256")      //or "SHA256"
  .then(
         function (signDataResp) {
           //Send signDataResp to Server
     },
         function (errmsg) {
             //Send errmsg to server or display the result in browser.
           }
  );

如果成功,则返回 Base64 编码的 pkcs7 签名 - 使用合适的库或 Signer.Digital 提供的库将签名注入 pdf

如果失败,则返回以“SDHost Error:”开头的错误消息

从浏览器进行数字签名

从浏览器进行数字签名

  1. 服务器将要签名的数据/文档/内容的哈希发送到浏览器。
  2. 浏览器使用 Signer.Digital Browser Extension Javascript API 从 Signer.Digital Browser Extension Host 调用操作。
  3. 在 Windows 上,浏览器扩展主机使用 Microsoft 证书存储和底层 CSP 来获得哈希签名。
  4. 在 Linux 上,浏览器扩展主机使用加密设备的 PKCS#11 .SO 库来获得哈希签名。
  5. 原始签名(哈希签名)或签名容器由Signer.Digital Browser扩展主机返回给浏览器。
  6. 如果是加密设备,即。USB 令牌或智能卡,用户的私钥永远不会从设备中出来,而是将要签名的哈希发送到设备以对其进行签名。
  7. Web 应用程序(浏览器中的 Javascript)将签名发送回服务器,并且可以在 PDF 文档、XML 或 Json 中或根据需要进行修改。
于 2019-04-14T14:26:41.287 回答
3

PDFSign.js,一个可以在浏览器中签署 PDF 文件的库。它使用伪造作为签名。如果 PKI.js 支持分离的 pkcs7 签名,那么替换 forge 应该很容易。

于 2015-12-25T00:05:13.783 回答
0

您可以使用 openpgp.js 签署任何文件(包括 pdf)

https://openpgpjs.org/openpgpjs/doc/#create-and-verify-detached-signatures

(向下滚动到“创建和验证分离签名”)

将文件读取为 Uint8Array 并使用您的私钥对其进行签名。

于 2019-12-31T17:20:41.657 回答