从通用浏览器访问智能卡的架构?或者:如何弥合从浏览器到PC / SC堆栈的差距?

问题描述 投票:46回答:12

从通用浏览器(通过http(s)连接到服务器),最好是从Javascript访问本地智能卡的可能的客户端架构有哪些,最终用户的安装麻烦最少?服务器需要能够至少向卡发出其选择的APDU(或者可能将其中的一部分委托给它生成的客户端代码)。我假设在工作PC / SC堆栈的客户端可用,配有智能卡读卡器。自XP,现代OS X和Unix以来,至少在Windows上这是一个合理的假设。

到目前为止,我已确定了以下选项:

  1. 一些自定义ActiveX。这就是我现有的应用程序所使用的(我们在内部开发),一旦获得安装ActiveX的许可,对IE的客户来说很容易部署,但它与“通用浏览器”要求不匹配。 更新:ActiveX主要由不推荐使用的IE支持,包括IE11;但不是边缘。
  2. 一些PC / SC浏览器扩展使用Netscape Plugin API,这似乎是上面的平滑扩展。我找到的唯一现成的是SConnect,但它似乎barely alive,其API documentation (webarchive)已不再正式提供,并且它与特定的智能卡供应商有很强的联系。原则可能很好,但为每个平台制作这样的插件将是很多工作。 更新:许多浏览器都删除了NPAPI支持,包括Chrome和Firefox。
  3. 一个Java Applet,运行在Oracle的JVM(1.)6或更高版本之上,它带有javax.smartcardio。从功能的角度来看,这很好,有充分的记录,我可以忍受一些已知的错误,但我害怕在接受Java-as-a-browser-extension时不可抗拒的向下螺旋。

还有其他想法吗?

另外:是否有某种方法可以防止恶意服务器滥用浏览器所拥有的任何PC / SC接口(例如,提供3个错误的PIN来阻止卡,只是为了它的肮脏;或者制造一些更邪恶的东西)。

cross-browser smartcard pcsc
12个回答
23
投票

更新(8/2016):正在讨论一种名为WebUSB API的Web新API。你可以already use it with Chrome v54+

该标准将在所有主流浏览器中实施,并将取代对Smard卡的第三方应用程序或扩展的需求:-)

所以新答案是肯定的!

类似OSI的架构堆栈是:


注意:谷歌在2017年宣布他们是will abandon Chrome Apps

上一个答案:

现在(2015年),您可以使用chrome.usb API创建Google Chrome应用。

然后通过其CCID-compliant界面访问智能卡读卡器。

它不是跨浏览器,而是JavaScript可编程和跨平台。

无论如何,现代浏览器不再支持Netscape Plugin API(NPAPI)。浏览器供应商正在驳斥Java applet。


0
投票

我有一个设置,扫描智能卡读卡器以登录用户。 PC / SC库在桌面上运行良好。有人提到使用Emscripten(https://github.com/kripken/emscripten)编译器将c ++编译成JavaScript代码。但这不能很好地工作,因为PC / SC使用的某些功能只能在服务器端使用。经过多方研究。我终于放弃了客户端解决方案,chrome web usb API也无法识别读者。 然后我决定尝试使用signalR并在连接到智能卡读卡器的PC上设置一个集线器,这种方法非常好。


0
投票

使用浏览器扩展程序访问智能卡或USB令牌

Java小程序,Active X等已经逐步淘汰或正在逐步淘汰新的Modern Browsers。最近有很多关于WebCrypto API的讨论,但截至目前,WebCrypto API不提供对(Windows)或任何其他Key存储或本地加密USB /智能卡设备的访问。

对于使用数字签名和PDF或eReturn签名从浏览器进行身份验证,可以使用一个免费的Chrome扩展程序是Signer.Digital chrome扩展。可以从https://signer.digital/downloads/Signer.Digital.Chrome.Host.Setup.zip下载本地系统(在Windows上的Chrome浏览器后面运行的主机)设置安装此主机并重新启动Chrome将自动添加Signer.Digital Chrome Extension

here说明了这个扩展的实际工作情况

测试步骤:

  1. 安装USB令牌或智能卡的设备驱动程序 - 这应该使您的证书在Windows证书存储区中
  2. 安装设置如上所示。
  3. 重启Chrome浏览器。
  4. 打开this link
  5. 输入UserID和Password并单击Register按钮 - 这将要求选择Digital Signature并在服务器上注册(仅适用于此会话 - 不是永久性的)。
  6. 然后再次输入相同的UserID和密码并选择相同的证书并单击Login。选择不同的证书将不允许登录。

Javascript从扩展名调用方法:

在服务器上注册证书:

//Get Selected Certificate Information 
SignerDigital.getSelectedCertificate()
    .then(
        function (CertInfo) {        
    //Success returns Certificate Subject and Thumbprint
        },
            function (errmsg) {
                //Send errmsg to server or display the result in browser.
              }
     );

要使用数字签名进行身份验证或登录:

SignerDigital.signAuthToken(authToken, "SHA-256")       //or "SHA256"
    .then(
        function (SignData) {        //Success returns Signed Auth Token
        },
            function (errmsg) {
                //Send errmsg to server or display the result in browser.
              }
     );

签署PDF:

    //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.
              }
     );

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


0
投票

这个问题的另一个解决方案叫做FortifyApp,你可以阅读它是如何工作的here

TL; DR;它是一个客户端可安装的应用程序,适用于OSX,Windows和Linux,通过Web加密polyfill公开智能卡,也可以提供对其他证书/密钥库的访问。


24
投票

事实上,除了建立SSL之外,浏览器不能将(加密)智能卡用于其他目的。

您需要使用浏览器执行的其他代码才能访问智能卡。

有几十个自定义和专有插件(使用你提到的所有三个选项)用于各种目的(签名是最受欢迎的,我猜),因为没有标准或普遍接受的方式,至少在欧洲,我相信其他地方同样。

创建,分发和维护自己的应用程序将是一个爆炸性的,因为浏览器每个月左右发布一次,每个新版本都会更改sanboxing和UI技巧,因此您可能需要经常调整代码。

您可能希望拥有GUI功能,至少是为了要求用户访问卡或其上的某些功能。

为了创建一个多平台,多个浏览器插件,可以使用像firebreath这样的东西。

就个人而言,我不认为将PC / SC暴露在网络上是有益的。 PC / SC本质上是一个低级协议,当暴露这个时,您也可以公开对磁盘的块级访问,并希望“Web上的应用程序只是我的,并且它们表现良好”(这应该回答你的“同时“)。同时像SConnect这样的瘦补丁是最容易创建的,用于提供javscript plugin.sendAPDU()样式代码(或者只是包装所有PC / SC API并让javascript调用者处理相同级别的细节与本机PC / SC API用例一样)。

为此目的创建插件通常是由于当前的严重缺陷所致。

解决未来(移动等)是另一个故事,像W3C webcrypto和OpenMobile API这样的东西最终可能会以某种方式创建一些东西,将客户端密钥容器暴露给Web应用程序。如果您的智能卡目标是加密,我的建议是避免使用PC / SC并使用平台服务(Windows上的CryptoAPI,OSX上的Keychain,Linux上的PKCS#11)

任何类型的设计都有要求。如果您考虑使用密钥而不是任意APDU,则这一切都适用。如果您的要求是发送任意APDU,请创建一个插件,然后继续使用它。


7
投票

我刚刚发布了一个解决此问题的beta插件。此测试版代码可在此处获得:

https://github.com/ubinity/webpcsc-firebreath

这个插件基于火呼吸框架,并已在Linux / WinXP / Win7下使用Firefox和Chrome进行了beta测试。提供源代码和扩展包。

基本思想是提供PCSLite API访问,然后在此基础上开发更友好的JS-api。

此插件正在积极开发中,因此请随时发送任何报告和请求。


4
投票

对于你的第一个问题,我没有希望:要么你对一小部分智能卡功能感到满意(比如签署电子邮件或PDF),那么你可以使用一些现成的软件(如PKCS),理想的是由智能卡公司,或者您想要更广泛的功能,需要为自己投入相当大的精力。当然,PCSC是选择的起点。

至少对你的“也:”有一些希望。

1)注意,某些规范(例如ICAO /德国BSI TR-3110)请求一种方法,其中PIN未被阻止,但是一旦错误计数器在回复之前命中1,则使用大量时间。必须使用不同的命令启用最终尝试,否则不会进行进一步的比较和错误计数器调整。

2)通过要求安全消息传递来简单地保护Verify命令。敏感应用程序对所有内容使用安全消息传递,因此第一步取消会话密钥,第二步应用于所有后续命令和响应。结果是,在完成错误计数器的比较或修改之前,该命令由于不正确的MAC而被拒绝。


4
投票

还有一个类似于@cslashm在http://github.com/cardid/WebCard上提出的浏览器插件。也是开源的,可以根据原始问题的要求安装“最小安装麻烦”。您可以看到访问http://plugin.cardid.org的一个使用示例

WebCard已经在IE 8到11,Windows中的Chrome和Firefox以及Mac OS X中的Chrome和Safari中进行了测试。由于它只是PC / SC的包装,它需要在Mac OS X中安装来自http://smartcardservices.macosforge.com的SmartCard服务


2
投票

由于chrome和firefox将停止NPAPI插件的支持,没有安全的解决方案可用于维护智能卡读取的会话,而你的卡的证书支持相互ssl,我回答类似的问题source,它可能救命


1
投票

它很脏,但如果它可以接受/可行在客户端机器上安装桥接守护进程/服务,那么你可以编写一个本地桥接服务(例如在python / pyscard中),通过REST接口公开智能卡,然后在在本地服务(外观)和远程服务器API之间进行调解的浏览器。


1
投票

说到Chrome,您现在可以使用Google提供的Smart Card Connector app,它捆绑了PC / SC-Lite端口和通用CCID驱动程序。

该应用程序本身通过之前的评论者提到的chrome.usb API工作。

因此,不是重写整个堆栈(从最低级别 - 原始USB开始),现在开发人员可以只编写在PC / SC API之上工作的部分 - 这是由Connector应用程序公开的。


0
投票

客户端,客户端,客户端...插件,... JSApis ..嗯..我们知道这一点:所有浏览器在与Apache或IIS服务器通信时,实际上在https / SSL握手过程中签署“某事”需要。

例如,典型的Apache配置如下:

SSLVerifyClient require
SSLVerifyDepth 10
SSLOptions +FakeBasicAuth +StdEnvVars +ExportCertData +OptRenegotiate

启动密码键盘弹出,用户必须插入智能卡引脚才能继续。

好吧,我的想法是:为什么不转向服务器,并调整那种行为,以便在启动握手时上传一个字节流的东西来签名?

© www.soinside.com 2019 - 2024. All rights reserved.