随着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&amp; amp;证书→签名Base64 PDF(发送到REST)
答案 0 :(得分:5)
技术上可以做到这一点,实际上这是我们制作PKIj时想到的场景之一(这就是为什么有这个样本) - https://pkijs.org/examples/PDFexample.html
说要做签名需要使用PDF结构本身,要么需要自定义解析器,要么修改现有解析器(例如pdfjs)。
长话短说,在浏览器中签署PDF需要做很多工作,这是我们正在努力的事情。
答案 1 :(得分:2)
有PDFSign.js,一个可以在浏览器中签署PDF文件的库。它使用forge作为签名。如果PKI.js支持分离的pkcs7签名,那么替换伪造应该很容易。
答案 2 :(得分:1)
到目前为止,WebCrypto API尚未提供对(Windows)或任何其他密钥存储区或本地加密USB /智能卡设备的访问。
在大多数签名方案中,出于保护服务器边界内pdf文件的要求,也不建议将完整的pdf文件发送到浏览器或签名API服务器。
因此,其优良作法是创建PDF哈希以进行签名,将哈希发送给浏览器并通过浏览器扩展使用javascript来访问在本地系统上运行的某些应用程序以访问本地密钥库(或USB /智能卡)并生成签名并将其发送回服务器(在使用PDF签名的情况下,将PKCS7或CMS容器)发送回服务器,在该服务器中,签名可以被注入回PDF,从该PDF创建散列以进行签名,然后将其发送到浏览器或签名api服务器。
对于基于浏览器的签名方案,Signer.Digital chrome扩展程序是一种可用的免费Chrome扩展程序。可以从https://signer.digital/downloads/Signer.Digital.Chrome.Host.Setup.zip或cNET Download site下载本地系统(运行于Windows chrome浏览器后面的主机) 安装此主机并重新启动Chrome会自动添加Signer.Digital Chrome Extension
此扩展程序的实际工作如图here
所示。从扩展名调用方法的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错误:”开头
答案 3 :(得分:0)
您可以使用openpgp.js签名任何文件(包括pdf)
https://openpgpjs.org/openpgpjs/doc/#create-and-verify-detached-signatures
(向下滚动到“创建并验证分离的签名”)
将文件读取为Uint8Array并使用私钥对其进行签名。