我已经跌了几个兔子洞,寻找答案。
我有一个用AngularJS编写的Web应用程序,当前需要IE11和Acrobat插件对PDF表单进行数字签名。但是,该插件在IE11上是垃圾邮件,现代浏览器(我将其定义为Firefox,Chrome和Edge)不支持该插件。我的公司不支持Safari。
因为该应用程序是AngularJS(并且不在Node上运行),所以我需要一个JavaScript解决方案来对PDF进行签名。不仅如此,签名证书还保存在智能卡上,这意味着我需要一个可以通过某种PKCS#11接口访问证书的密码库。用Java语言编写。客户目前不接受在Acrobat中从外部打开表单。
我查看了多个库,但找不到一个直接的答案:
这些软件包都没有向我提供足够的信息,以了解是否需要进一步研究它们。
外面有人可以向我提供更多信息或指示吗?
谢谢, 杰森
答案 0 :(得分:1)
此答案针对解决方法,而不是实际答案。
这是因为当前浏览器中没有 API ,您可以用来获取和使用智能卡证书的私钥。据推测,这已经在Web Crypto API中进行了讨论,据我所知-共识是出于安全原因(我完全不同意!),不应该支持此方法。
您和成百上千的其他开发人员(包括我们在内)都不走运。
第一个解决方法涉及一个.NET ClickOnce桌面应用程序,该应用程序部署在服务器上并从服务器运行。该应用程序通过运行时参数获取当前用户会话的安全上下文,以便在浏览器和在浏览器旁边运行的应用程序之间共享该会话。从这个意义上说,独立运行此应用程序(在浏览器中没有会话)将在与服务器通信期间导致授权问题。
该应用使用服务器的API首先检索用户将要签名的文档。然后,应用程序无限制地使用本地证书存储(因为它是常规的桌面应用程序),对文档进行加密并将其发送回服务器。
优点:可以从浏览器中调用ClickOnce应用。
缺点::这需要客户端运行.NET。
第二种解决方法涉及一个Java桌面应用,该应用独立安装在客户端计算机上。您为选定的操作系统(例如Windows,Linux,MacOS)提供安装软件包,用户下载安装软件包并在其操作系统中安装应用程序。
然后,当浏览器应该对文档进行签名时,您将提供一条指令,告诉用户在后台运行该应用程序。该应用程序在运行时会通过两项服务
在本地主机和固定端口上公开HTTP侦听器您猜想,是浏览器执行请求,浏览器向localhost:port
发出请求,然后将文档数据上传到推送服务。 Java应用程序从等待文档切换到签署文档状态。用户应该使用该应用程序-从商店中选择一个证书(由于是常规的Java桌面应用程序,因此没有任何限制)并签署文档。您的浏览器在后台 ping 应用程序的提取服务中,当数据准备就绪时,浏览器将下载它。然后,浏览器使用经过身份验证的实际会话将签名的文档上传到实际的服务器。
此处存在潜在的安全漏洞,因为任何本地应用程序或任何打开的网页都可以ping拉服务并下载文档(当然您不希望这样做)。我们知道有两个解决方法。
首先,您可以在Java应用程序中拥有另一个服务,该服务返回一次性身份验证令牌(例如guid),该令牌将被读取一次,然后随对pull服务的每次调用一起提供为身份验证令牌。 。如果其他恶意应用程序或网页在您的应用程序网页之前 读取了令牌,则您的页面将从提取服务中获取错误(因为一次性令牌显然已被盗,并且不可用)。该网页可能在此处发出通信错误信号,并警告用户潜在的安全问题。
修复漏洞的第二种方法涉及到应用程序服务器提供的pull服务调用的参数,并将该参数作为值放入页面的脚本中,该令牌由服务器证书签名。您的Java应用程序可以具有服务器证书的公钥,以便Java应用程序能够验证自变量的签名。但是没有其他应用程序(也没有其他页面)能够伪造令牌(因为令牌的签名的私钥仅在您的服务器上可用),并且没有简单的方法可以从页面的主体中窃取有效令牌。
优点:Java应用程序可能针对多个操作系统 缺点:这仍然需要客户端上的Java运行时
这两种变通办法均已在生产中进行了测试,并且都可以使用多年。我希望这为您提供最终解决方案的可能方向。
答案 1 :(得分:1)
@Json,您说过“这不是我想听到的,但我会接受您的回答。” !!
我建议使用浏览器扩展对pdf,文件或现代浏览器中的任何内容进行数字签名。浏览器扩展将插入浏览器之间,该浏览器将提供JavaScript的浏览器连接到本地运行的扩展主机(应用程序)并访问CertStore。
我们公司发布了一个这样的扩展名,并且是免费的,它使用.NET Framework 3.5,该版本通常在所有Windows客户端上都可用。它不使用PKCS#11只是消除了提供PKCS#11驱动程序等的需要,并且仅在成功安装后才能透明地工作。它使用Windows CertStore。
根据您的评论,您有更多运行Firefox的客户端,但是我们正在开发Edge和Firefox扩展。
(在Windows的chrome浏览器后面运行的主机应用程序的)设置可以从https://download.cnet.com/Signer-Digital-Chrome-Extension/3000-33362_4-78042540.html下载 安装此主机并重新启动Chrome会自动添加Signer.Digital Chrome扩展程序
此扩展程序的实际工作如图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签名-使用任何合适的库将符号注入pdf 如果失败,则返回错误消息,以“ SDHost错误:”开头
我希望这会有所帮助!
答案 2 :(得分:-1)
自 2016 年以来我一直在寻找这样的东西。在巴西,我们有 Lacuna Software WEBPKI,但它一定很贵。
我昨天发现了这个:https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/pkcs11