使用普通JavaScript为PDF签名

使用普通JavaScript为PDF签名,javascript,pdf,sign,signing,webcrypto-api,Javascript,Pdf,Sign,Signing,Webcrypto Api,随着WebCryptoAPI的发展和Chrome和Firefox的支持,我想用它对PDF文档进行数字签名。相关文献不多,但我找到了一些示例[1]和一个名为PKI.js的库[2]。在这些示例中,描述了签名过程,但最后返回了签名。我希望我的Base64 PDF文件再次以带签名的Base64字符串返回,但遗憾的是,事实并非如此。据我所知,PKI.js也没有提供对我的Base64 PDF进行签名的方法 有没有办法只使用JavaScript和WebCryptoAPI签署PDF?私钥可以在中输入,或者更好地

随着WebCryptoAPI的发展和Chrome和Firefox的支持,我想用它对PDF文档进行数字签名。相关文献不多,但我找到了一些示例[1]和一个名为PKI.js的库[2]。在这些示例中,描述了签名过程,但最后返回了签名。我希望我的Base64 PDF文件再次以带签名的Base64字符串返回,但遗憾的是,事实并非如此。据我所知,PKI.js也没有提供对我的Base64 PDF进行签名的方法

有没有办法只使用JavaScript和WebCryptoAPI签署PDF?私钥可以在
中输入,或者更好地存储在浏览器的证书设置中

Base64 PDF(来自RESTAPI)→ 使用JS证书签名(&C)→ 已签名Base64 PDF(发送至REST)

  • [1]
  • [2]

从技术上讲,这样做是可能的,事实上,这是我们在制作PKIjs时想到的场景之一(这就是为什么会有这个示例)——

也就是说,做签名需要使用PDF结构本身,这需要自定义解析器或修改现有解析器(例如pdfjs)


长话短说,在浏览器中为PDF文件签名需要很多工作,这是我们正在进行的工作。

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

披露:我为CISPL工作

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

此外,在大多数签名场景中,出于保护服务器边界内pdf文件的要求,不建议将完整的pdf文件发送到浏览器或签名API服务器

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

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

此扩展的实际工作过程与完整的代码演练以及工作示例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:”开头的错误消息:

从浏览器进行数字签名

您可以使用openpgp.js对任何文件(包括pdf)进行签名

(向下滚动至“创建并验证分离的签名”)


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

我想对纯文本进行签名,因此使用此库可以这样做吗?我没有找到一个可以读取p12证书+私钥并生成签名的示例。你可以用它签名任何东西。此示例对任意文件进行签名-此示例显示导入PKCS#12s-有关一些限制和实现说明,请参阅。“其良好做法…”-好的,什么是良好做法,取决于您更信任哪个应用程序。您的答案假设服务器应用程序是可信的,可以信任它为用户想要签名的pdf提供哈希。对于第一次处理某个服务器应用程序的用户来说,这种假设可能不正确,因为他碰巧在自己的计算机上有一个他信任的签名应用程序。@mki,我指的是在服务器上生成的pdf。如果用户在自己的计算机上有PDF,那么有很多可用的工具,包括最常用的Acrobat Reader来签署PDF文档。。。但问题是关于使用JavaScript进行签名,这意味着文档在服务器上,签名在浏览器上。“我说的是在服务器上生成pdf。”-即使如此,如果我不相信服务器会向我发送正确的哈希,我(作为用户)希望能够通过下载pdf来应用签名,使用受信任的软件在本地签名,然后再次上载签名的pdf。不过,我必须承认,任意的浏览器扩展在这里并不是真正值得信任的软件,因此在这里,用例是否只向我传输一个散列文件或整个文档确实无关紧要……一些例子是我在公司的Web应用程序上刚刚准备好的发票或PO签名(比如CRM或基于Web的会计软件)我想最后把这个标志。另一个例子是我刚刚在我的公司web应用程序或eReturn服务提供商的web UI上预览的eReturn,我不喜欢在签名之前查看return的XML或Json。。只是想帮助那些值得信任的案子。。。你想让我把“良好实践”换成“普通实践”?!:)不需要改变任何东西。如果用户有理由信任有问题的服务器(例如,由适当的CC认证支持),该解决方案确实有其魅力。每当人们想要签名并强调他们想要签名pdf文件时,他们通常意味着他们想要使用集成的pdf签名,而不是使用独立的签名文件进行签名。这意味着,对于可互操作的签名,PKCS#1/PKCS#7格式基于X.509证书,而不是PGP格式。