javascript-在现代Firefox / Chrome / Edge浏览器中对PDF进行数字签名
作者:互联网
我已经跌了几个兔子洞,寻找答案.
我有一个用AngularJS编写的Web应用程序,当前需要IE11和Acrobat插件对PDF表单进行数字签名.但是,该插件在IE11上是垃圾,现代浏览器(我将其定义为Firefox,Chrome和Edge)不支持该插件.我公司不支持Safari.)
因为应用程序是AngularJS(并且不在Node上运行),所以我需要一个JavaScript解决方案来对PDF进行签名.不仅如此,签名证书还保存在智能卡上,这意味着我需要一个可以通过某种PKCS#11接口访问证书的密码库.用Java语言编写.客户目前不接受在Acrobat中从外部打开表单.
我查看了多个库,但无法找出一个简单的答案:
> PKI.js
> pkcs11.js
> hwcrypto.js
> graphene.js
这些软件包都没有为我提供足够的信息,以了解是否需要进一步研究它们.
有人可以向我提供更多信息或方向吗?
谢谢,
杰森
解决方法:
该答案针对解决方法,而不是实际答案.
这是因为当前您可以用来获取和使用智能卡证书的私钥的浏览器中没有API.据推测,这已经在Web Crypto API中进行了讨论,据我所知-共识是出于安全原因(我完全不同意!),不应该支持此方法.
您和成百上千的其他开发人员(包括我们在内)很不走运.
第一种解决方法是在服务器上部署并从服务器运行的.NET ClickOnce桌面应用程序.该应用程序通过运行时参数获取当前用户会话的安全上下文,以便在浏览器和在浏览器旁边运行的应用程序之间共享该会话.从这个意义上说,独立运行此应用程序(在浏览器中没有会话)将在与服务器通信期间导致授权问题.
该应用程序使用服务器的API来首先检索用户将要签名的文档.然后,应用程序无限制地使用本地证书存储(因为它是常规的桌面应用程序),对文档进行加密并将其发送回服务器.
优点:可以从浏览器中调用ClickOnce应用程序.
缺点:这需要在客户端运行.NET.
第二种解决方法是在客户端计算机上独立安装Java桌面应用程序.您为选定的操作系统(例如Windows,Linux,MacOS)提供安装软件包,用户下载安装软件包并在其OS中安装应用程序.
然后,当浏览器应该在文档上签名时,您将提供一条指令,告诉用户在后台运行该应用程序.该应用程序在运行时会在本地主机和具有两个服务的固定端口上公开HTTP侦听器
>推送服务,接受要签名的文档数据
>提供签名文件(如果可用)的拉取服务
如您所料,是浏览器执行请求,浏览器向localhost:port发出请求,然后将文档数据上传到推送服务. Java应用程序从等待文档切换到签署文档状态.用户应该使用该应用程序-从商店中选择一个证书(由于是常规的Java桌面应用程序,因此没有任何限制)并签署文档.您的浏览器在后台ping该应用程序的提取服务,并在数据准备就绪后下载它.然后,浏览器使用实际的经过身份验证的会话将签名的文档上载到实际的服务器.
这里存在潜在的安全漏洞,因为任何本地应用程序或任何打开的网页都可以ping拉服务并下载文档(当然您不希望这样做).我们知道有两个解决方案.
首先,您可以在Java应用程序中拥有另一个服务,该服务返回一次性身份验证令牌(例如guid),该令牌将被读取一次,然后在每次调用pull服务时都将其作为身份验证令牌提供.如果有任何其他恶意应用程序或网页在您的应用程序网页之前读取了令牌,则您的页面将从拉取服务中获取错误(因为一次性令牌显然已被窃取并且不可用).该网页可能在此处发出通信错误信号,并警告用户潜在的安全问题.
解决漏洞的第二种方法涉及到应用程序服务器提供的pull服务调用的参数,并将该参数作为值放入页面的脚本中,该令牌由服务器的证书签名.您的Java应用程序可以具有服务器证书的公钥,以便Java应用程序能够验证自变量的签名.但是没有其他应用程序(也没有其他页面)能够伪造令牌(因为令牌的签名的私钥仅在您的服务器上可用),并且没有简单的方法可以从页面的主体中窃取有效令牌.
优点:Java应用程序可能针对多个操作系统
缺点:这仍然需要客户端上的Java运行时
两种解决方法都已在生产中进行了测试,并且都可以很好地工作多年.我希望这为您提供最终解决方案的可能方向.
标签:pkcs11,javascript 来源: https://codeday.me/bug/20191210/2104898.html