Architectures to access Smart Card from a generic browser? Or: How to bridge the gap from browser to PC/SC stack? [closed]
Asked Answered
S

11

62

What are the currently existing and supported client-side architectures to access a local Smart Card thru a PC/SC Smart Card reader (ISO 7816-3, ISO 14443) from a generic browser (connected to a server through http(s)), preferably from Javascript, with the minimum installation hassle for the end user? The server needs to be able to at least issue APDUs of its choice to the Smart Card (or perhaps delegate some of that to client-side Javascript code). I am assuming availability on the client side of a working PC/SC stack, complete with Smart Card reader. That's a reasonable assumption at least on Windows since XP, modern OS X and Unixes.

I have so far identified the following options:

  1. Some custom ActiveX. That's what my existing application uses (we developed it in-house), deployment is quite easy for clients with IE once they get the clearance to install the ActiveX, but it does not match the "generic browser" requirement.
    _update, Jan 2024]: ActiveX is supported mostly by the deprecated IE, including IE11; it still works in Edge in IE compatibility mode, but clearly it's dying.
  2. Some PC/SC browser extension using the Netscape Plugin API, which seems like a smooth extension of the above. The only ready-made one I located is SConnect (webarchive). It's no longer promoted (Update: thought still actively maintained and used late 2020 in at least one application), it's API documentation (webarchive) is no longer officially available, and it has strong ties to a particular Smart Card and reader vendor. The principle may be nice, but making such a plugin for every platform would be a lot of work.
    Update: NPAPI support is dropped by many browsers, including Chrome and Firefox.
  3. A Java Applet, running on top of Oracle's JVM (1.)6 or better, which comes with javax.smartcardio. That's fine from a functional point of view, well documented, I can live with the few known bugs, but I'm afraid of an irresistible downwards spiral regarding acceptance of Java-as-a-browser-extension. [update, Jan 2024]: in-browser Java applets are essentially gone.
  4. [update, Feb 2021]: This answer considered the WebUSB API as a promising solution solution in 2015, then reported in 2019 that can't work or is abandoned. I made a question about it there. [update, Jan 2024]: This never became mainstream, much less cross-browser.
  5. [update, Jan 2024]: The Web Authentication API allows some usages of some Smart Cards, but not AFAIK not sending arbitrary APDUs.
  6. [update, Jan 2024]: WebCard, but it requires installation of a local application (at least in Windows), and my understanding is that it is Chrome-specific.

Any other idea?

Also: is there some way to prevent abuse of whatever PC/SC interface the browser has by a rogue server (e.g. presenting 3 wrong PINs to block a card, just for the nastiness of it; or making some even more evil things).

Stodder answered 4/4, 2013 at 9:14 Comment(6)
Have you seen #8793399Hagiographa
@flup: thank for the pointer. It looks like the solutions listed there are PKCS#11-oriented, when the Smart Cards that I target (a wild mix of cards for the payment of public transport) are not.Stodder
Java Applet is a subset of NPAPI plugin solution.Purim
Now that Chrome no longer supports NPAPI, maybe an update would be in order...Valency
In my case I installed a signalR hub as a Windows service on the PC connected to the reader worked out well for me.Ferule
I've basic question - is the server demands client certificate in the response, or the browser sends it along with the first request? I'm trying to relate it to SPNEGO where - browser sends the kerberos/ntlm ticket only after receiving 401/Negotiate response from the server. Do we have similar case here? If yes, is there any specific http response code/header to tell browser to get client cert?Piperpiperaceous
S
29

The fact is that browsers can't talk to (cryptographic) smart cards for other purposes than establishing SSL.

You shall need additional code, executed by the browser, to access smart cards.

There are tens of custom and proprietary plugins (using all three options you mentioned) for various purposes (signing being the most popular, I guess) built because there is no standard or universally accepted way, at least in Europe and I 'm sure elsewhere as well.

Creating, distributing and maintaining your own shall be a blast, because browsers release every month or so and every new release changes sanboxing ir UI tricks, so you may need to adjust your code quite often.

And you probably would want to have GUI capabilities, at least for asking the permission of the user to access a card or some functionality on it.

For creating a multiple-platform, multiple browser plugin, something like firebreath could be used.

Personally, I don't believe that exposing PC/SC to the web is any good. PC/SC is by nature qute a low level protocol that when exposing this, you could as well expose block level access to your disk and hope that "applications on the web are mine only and they behave well" (this should answer your "Also"). At the same time a thin shim like SConnect is the easiest to create, for providing a javscript plugin.sendAPDU()-style code (or just wrap all the PC/SC API and let the javascript caller take care of the same level of details as in native PC/SC API use case).

Creating a plugin for this purpose is usually driven by acute current deficiencies.

Addressing the future (mobile etc) is another story, where things like W3C webcrypto and OpenMobile API will probably finally somehow create something that exposes client-side key containers to web applications. If your target with smart cards is cryptography, my suggestion is to avoid PC/SC and use platform services (CryptoAPI on Windows, Keychain on OSX, PKCS#11 on Linux)

Any kind of design has requirements. This all applies if you're thinking of using keys rather than arbitrary APDU-s. If your requirement is to send arbitrary APDU-s, do create a plugin and just go with it.

Slater answered 7/4, 2013 at 7:40 Comment(6)
+1 for the idea of using a generic browser plugin framework, did not know firebreath. Yes I need generic APDU access, for the application calls for support of a wide and evolving range of Smart Cards. Also, having a dedicated, e.g. signing plug-in is not intrinsically safer then having an APDU-plugin: if the Smart Card is here to sign, we do not want a rogue server to use the plug-in to sign anything.Stodder
Of course not. Such signature plugins often take care of (questionable) legal warnings ("You are about to sign a legally binding etc et") and schemes like WYSIWYS (at least better than just signing something). The point here is that the plugin provides a fixed set of higher level functionality where the locally installed code (can be signed etc) takes care of some protection of the overall model and asks the user permission for things the user can understand.Slater
("do you want to sign something?" yes/no. Do you want to sign "blablabla" on site example.com, then please enter your PIN code"; user understands that a PIN entry dialog that keeps popping up is bad; user understands that a window popping up on random webpage is bad etc) whereas "Android style" "Do you want website X to be granted access to your smart card(s)" opens a huge window of possibilities and assuming that a user can individually approve every APDU is ... strange.Slater
Oh, and anyway, a per-server "allow access" question (much like it works with cookies, JS and everything else in modern browsers) is a simple necessity these days. But a rogue server (better call this a dedicated attacker) has other ways to get the JS to run.Slater
SSL is not the typical smart card task, since the key involved is newly negotiated, used for one session only and has no need of a long term highly protected secret, as a private key. I would flag user authentication as most important job.Grandsire
@Grandsire As we are talking smart cards I also meant SSL authentication with client certificates (and keys) from the card.Slater
D
26

Update (8/2016): A new API for the Web called WebUSB API is being discussed. You can already use it with Chrome v54+.

This standard will be implemented in all major browsers and will replace the need for third-party applications or extensions for Smard Cards :-)

So the new answer is YES!

And the OSI-like architecture stack is:

2019 Update: As @vlp commented, it seems that it doesn't work any in Chrome because they decided to block WebUSB for smartcards for some specious reasons :-(


Note: Google annonced that they will abandon Chrome Apps in 2017.

Previous anwser:

Now (2015) you can create a Google Chrome App, using the chrome.usb API.

Then you access the smartcard reader via its CCID-compliant interface.

It's not cross-browser but JavaScript programmable & cross-platform.

Anyway Netscape Plugin API (NPAPI) is not supported any more by modern browsers. And Java applets are being dismissed by browser vendors.

Darrel answered 24/9, 2015 at 14:18 Comment(8)
Unless you are running ChromeOS, I doubt you can connect to a smart card reader through the chrome.usb API. If the OS has a driver handling the device (which would be the case for a typical CCID reader), the chrome.usb will be denied access to the device (see the caveats section in the link you provide). Moreover, coding the CCID and T=0/T=1 protocol stacks in JavaScript would surely be a pain.Bizet
@dim. You can do it. I did it. Works on Windows 7-10.Darrel
Seriously ?!!! I couldn't imagine that. But if you say so, then, it's worth I try on my side. And if it actually works, I'll bless you every day god makes. And I'm starting with an upvote at once. But I still doubt... How the OS manages to make the peripheral both available to the chrome.usb API and the PC/SC driver at the same time ?Bizet
I've used the WinUSB (or libusb, or libusb-K) generic driver instead of the vendor (Omnikey)'s one, which wasn't recognized by Chrome. You can hire me if you need ;-). I didn't implement the whole PC/SC stack but I can select DF / read / write EF / perform hash / abort.. for short APDU. I was a pain you're right.Darrel
All right, so there is a trick, which is not to use the vendor's driver. It seemed to good to be true, indeed. Well, I'm not sure whether this is applicable to my case, then. Anyway, it's good to know. Thanks. Now, as to hiring you, I'll keep that in mind, but don't build too many hopes :)Bizet
Maybe some drivers from other vendors are already compliant with Chrome. I opened a case at HID Global and they say their Omnikey driver will be updated in 2016 (it was last year) to support Chrome. I've not tested other devices than Omnikey 3121. I'll try soon with the ACR39.Darrel
Unfortunately Chrome started to block smart card readers in WebUSB API (see e.g. here and here)Acerbic
Any hope now in 2022?Cavendish
L
7

I have just released a beta plugin addressing this problem. This beta code is available here:

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

This plugin is based on the firebreath framework and has been beta-tested with Fireofx and Chrome under Linux/WinXP/Win7. Source code and extension pack are provided.

The basic idea is to provide a PCSLite API access and then develop a more friendly JS-api on top of this.

This plugin is under active development, so feel free to send any report and request.

Lekishalela answered 3/6, 2013 at 9:6 Comment(1)
As far as I understand this is based on NAPI, which is obsolete.Stodder
G
4

For your first question I have little hope: either you are satisied with a very small subset of smart card functionality (like signing e-Mail or PDFs), then you may use some ready-made software (like PKCS), ideally maintained by the smart card company, or you want broader functionality and need to invest considerable effort on your own. Surely PCSC is the starting point to choose.

At least for your "also:" there is some hope.

1) Note, that some specifications (e.g. ICAO/German BSI TR-3110) request a method, where a PIN is not blocked, but uses a substantial amount of time as soon as the error counter hits 1 before replying. The final attempt must be enabled using a different command, otherwise no further comparison and error counter adjustment is done.

2) Simply protect the Verify command by requiring secure messaging. Sensitive applications use secure messaging for everything, so first step a session key is negtiated, which is second applied to all succeeding commands and responses. The effect would be, that the command is rejected due to incorrect MACs long before a comparison or modification of error counter is done.

Grandsire answered 4/4, 2013 at 12:54 Comment(1)
You leave the question of how to bridge the gap between browser and PC/SC unanswered. I shall rephrase my question perhaps. Also: 1) Nice, did not knew that. 2) Secure messaging requires a secret; that prevents using the PIN in its traditional use case: offline, SAM-less POST.Stodder
S
4

There is another browser plugin similar to the one proposed by @cslashm available at http://github.com/cardid/WebCard. Is also open source and can be installed with "minimum installation hassle" as required in the original question. You can see an example of use visiting http://plugin.cardid.org

WebCard has been tested in IE 8 through 11, Chrome and Firefox in Windows and in Chrome and Safari in Mac OS X. Since is just a wrapper for PC/SC it requires in Mac OS X the installation of SmartCard Services from http://smartcardservices.macosforge.com

Superfamily answered 16/11, 2014 at 14:59 Comment(6)
It runs also on linux?Euromarket
The plugin uses the http:://firebreath.org framework that also supports Linux, but I have not tried to build for that platform. @giuseppe Do you have build tools to give it a try?Superfamily
Hi. With build tools you mean gcc and brothers? Yes I have it...Could you guide me?Euromarket
@giuseppe you can look at firebreath.org/display/documentation/Building+on+Linux and once you have an example Firebreath plugin building in Linux you can then try to build a Linux version of WebCard.Superfamily
Could you tell me where the doc is? I do not understand how to send command to the smart card in order to read its certificates...Euromarket
January 2024: It looks like WebCard is Chrome-only. As an aside, the documentation mentions an install.bat, but it's not in the git, nor is there anything that builds it. The javascript links to an online webcard.msi but sadly there is no instruction for building that and it's not signed (however webcard.exe that it installs has a makefile and is signed by Adrian Castillo, if with SHA-1).Stodder
A
2

As chrome and firefox going to stop the support of NPAPI Plugin, there is no secure solution available to maintain the session for the smart card reading instead your certificate of the card have support for mutual ssl ,I answered for the similar question source,It might help

Array answered 27/12, 2015 at 18:19 Comment(0)
R
2

Its dirty, but if its acceptable / viable to install a bridge daemon/service on the client machine, then you can write a local bridge service (e.g. in python / pyscard) that exposes the smartcard via a REST interface, then have javascript in the browser that mediates between that local service (facade) and the remote server API.

Retrograde answered 24/5, 2016 at 13:9 Comment(0)
A
2

Web Serial API (draft) can be used to communicate with a serial smart card reader from some browsers.

Buyer beware: This API is a draft and may be changed/abandoned at any time.

Acerbic answered 16/9, 2022 at 0:28 Comment(4)
Can you give an example of how to use the API?Cavendish
@Cavendish There are several generic tutorials for this API and different serial readers use different protocols. I have a working PoC for ACR1281S serial reader that I unfortunately cannot share.Acerbic
This is for serial (rather than PC/SC) readers, thus does not answer the question.Stodder
You are right, but as long as there is no working solution for USB readers, using a serial reader is the only possible way.Acerbic
H
1

Speaking about Chrome, you can now use the Smart Card Connector app provided by Google which bundles the PC/SC-Lite port and the generic CCID driver.

The app itself works through the chrome.usb API, that was mentioned by the previous commenters.

So, instead of rewriting the whole stack (starting from the lowest level - raw USB), it's now possible for developers to code only the part that works on top of PC/SC API - which is exposed by the Connector app.

Handpick answered 18/7, 2016 at 17:27 Comment(3)
As now noted in that other answer, Google announced that they will abandon Chrome Apps in 2017. Thus solutions based on the Smart Card Connector app or/and chrome.usb API have been short-lived.Stodder
@Stodder The Smart Card Connector app is still maintained and works (it's already been 5 years since your comment). Chrome Apps deprecation has been delayed multiple times, and even post-deprecation we'll migrate to a different technology.Handpick
As of Jan 2024, this seems to be ChromeOS-only. Isn't it ?Stodder
B
1

Clients,clients,clients...plugins,..JSApis.. Well.. For certain we know this : All browsers, when communicating to an Apache or IIS servers, are actually signing "something" when a https/SSL handshake process is needed.

For instance, a typical Apache configuration like this:

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

Initiates a PIN pad pop up and the user must insert the smartcard pin to go on.

Well, my idea is : why not make the turn to the server, and tweak that behaviour, in order to upload a bytestream of stuff to sign something when a handshake is initiaded?

Benitez answered 16/3, 2017 at 10:0 Comment(1)
The application is not signing. It does require sending arbitrary APDUs to the Smart Card.Stodder
F
0

I have a setup where a smartcard reader is scanned to login a user. The PC/SC library work great on desktop. Somebody had mentioned to use Emscripten (https://github.com/kripken/emscripten) compiler which compiles c++ into JavaScript code. But that didn't work well because some of the functions being used by PC/SC are only available server side. After much research. I finally gave up on a client side solution, chrome web usb API also couldn't recognize the reader.
I then decided to give signalR a try and set up a hub on the PC connected to the smartcard reader and this approach worked out very well.

Ferule answered 15/2, 2018 at 2:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.