Storing Cryptographic Keys in Persistent Browser Storage

This blog post is a companion to a presentation made at the 2017 International Cryptographic Module Conference and refers to the presentation slides, revised after the conference. Karen Lewison is a co-author of the presentation and of this blog post.

Slide 2: Key storage in web clients

Most Web applications today use TLS, thus relying on cryptography to provide a secure channel between client and server, and to authenticate the server to the client by means of a cryptographic credential, consisting of a TLS server certificate and its associated private key. But other uses of cryptography by Web applications are still rare. Client authentication still relies primarily on traditional username-and-password, one-time passwords, proof of possession of a mobile phone, biometrics, or combinations of two or more of such authentication factors. Web payments still rely on a credit card number being considered a secret. Encrypted messaging is on the rise, but is not Web-based.

A major obstacle to broader use of cryptography by Web applications is the problem of where to store cryptographic keys on the client side. Smartcards provide strong security for the storage of cryptographic keys, but most Web app developers cannot ask their users to use smartcards and card readers. Windows machines have Trusted Platform Modules (TPM), which can be used to implement “virtual smart cards”, obviating the need for physical smart cards and readers; but most developers cannot require their users to use Windows machines. A few years ago Microsoft introduced Windows CardSpace, which allowed users to authenticate with “InfoCards” containing various kinds of credentials, including traditional certified key pairs consisting of a public key certificate and its associated private key, and U-Prove tokens that provided selective disclosure of attributes and issue-show unlinkability; but CardSpace was soon discontinued, due to lack of acceptance, which was not surprising since it was Windows-specific. It used to be possible to store cryptographic keys in ordinary files, accessed by Java applets, but Java applets are now being deprecated by Web browsers.

TLS supports client authentication in addition to server authentication, but TLS client authentication is only suitable for specific use cases. Using client authentication requires creating a TLS client certificate and importing it into the browser. This can be done manually or automatically. Doing it manually involves creating a certificate-signing request using, e.g., OpenSSL, submitting it to a certificate authority, retrieving the resulting certificate, and using a browser user interface to import it. Web app developers cannot ask non-technical users to do this. Doing it automatically requires a computing environment set up by professional IT personnel, such as Active Directory and/or Mobile Device Management, and is therefore only feasible within an enterprise or other large organization.

Several attempts have been made to make it easier for web applications to store cryptographic keys on the client side.

HTML5 introduced the <keygen> HTML tag, which was intended to allow a Web server to issue a TLS client certificate that would be automatically imported into the browser. But it was not supported by Internet Explorer, which at the time was still the dominant browser, and it has recently been deprecated.

The recent FIDO specifications allow a browser to authenticate to the back-end of a Web application using a key pair generated and stored by an “authenticator” accessible to the browser. The authenticator could be a hardware device or component such as a USB dongle, a TPM, a secure element or a TEE, or could be implemented in software. The authenticator attests to the application back-end that it belongs to a particular class of devices by signing the authentication public key with an attestation private key, all devices in the class carrying the same attestation private key.

In FIDO UAF, where UAF stands for “Universal Authentication Framework”, the user activates the authenticator by authenticating to it with a biometric sample or a PIN. In FIDO U2F, where U2F stands for “Universal Second Factor”, the authenticator should be a separate hardware device whose possession serves as a second authentication factor. The authenticator device may communicate with the user’s primary computing device via USB or NFC. The user activates the authenticator device by pressing a button on the device, or, if an NFC device, by tapping it against the primary computing device. This does not count as an authentication factor; the other authentication factor is instead an ordinary username and password. The W3C has adopted FIDO U2F as the foundation for the Web Authentication API.

FIDO requires browser plugins, but new web technologies have appeared over the last few years that enable new key storage solutions without plugins. This post and the companion presentation focus on the storage of keys used in cryptographic credentials, but the techniques discussed below can also be adapted for other purposes, briefly mentioned below in connection with Slide 27.

Slide 3: New Web technologies

Five Web technologies have appeared over the last few years that enable new solutions for storing cryptographic keys in persistent browser storage. These technologies are Web APIs that browsers make available to JavaScript code embedded in Web pages. They include, in chronological order, the Web Storage API, the IndexedDB API, the Web Cryptography API, the Service Worker API and the Web Authentication API.

Slide 4: The Web Authentication API

The Web Authentication API is based on the FIDO U2F specification described above, whose adoption by the W3C may eliminate the need for browser plugins. It is scheduled to become available without plugins on Chrome, Firefox and Edge later this year.

The Web Authentication API provides a new solution to the problem faced by web applications of how to store client-side cryptographic credentials. The authentication key pair is stored in the authenticator, which is accessible to the browser. Since the authenticator should be a separate hardware device, this does not seem very different from storing credentials in a smart card. But the same authenticator may be shared by any number of web applications, and provisioning is automated. On the other hand the authenticator can only store uncertified key pairs, and the Web Authentication API can only be used to authenticate repeat visits of a user who has previously registered with the application. It cannot be used for identity proofing or for claiming attributes certified by an authoritative third party. Therefore it does not provide a general purpose key-storage solution.

The other four web technologies are not specifically intended for the storage of cryptographic keys, but they can be combined in several ways to obtain general purpose key-storage solutions. They are reviewed in chronological order in slides 5-8.

Slide 5: The Web Storage API

The Web Storage API is available in all browsers (including Opera but not Opera Mini, which does not support any of the APIs that we are concerned with). It was introduced as part of the WHATWG HTML5 specification, and has been available in most browsers since 2009, before HTML5 was officially adopted by the W3C in 2014. (Detailed availability history for all the Web technologies discussed here can be found at caniuse.com.) It is very simple. It allows JavaScript code to store strings as properties of a localStorage object or a sessionStorage object, with the former providing persistent storage. Stored data is protected by the same origin policy implemented by all browsers. In first approximation, this means that if a string is stored by JavaScript code embedded in a web page downloaded from a particular DNS domain, it can only be retrieved by JavaScript code that is also embedded in a web page downloaded from the same DNS domain.

Slide 6: The IndexedDB API

The IndexedDB API also provides persistent storage. It is available in all browsers today and has been available in most browsers since 2012. By contrast with the Web Storage API, it has a complex asynchronous interface, which has earned it this warning in the IndexedDB API page of the Mozilla Developer Network: “IndexedDB API is powerful, but may seem too complicated for simple cases”. On the other hand it can store arbitrary JavaScript objects rather than simple JavaScript strings. Not having to convert an object to a string is only a matter of convenience in the case of an ordinary object, but makes a big difference when the object to be stored is a cryptographic key, as explained below. Data stored through the Indexed DB API is protected by the same origin policy of the browser, just like data stored through the Web Storage API.

Slide 7: The Web Cryptography API

The Web Cryptography API has been supported by most browsers since 2014. It is available in all browsers today, but Internet Explorer only supports an old version of the specification, and Safari requires API references to be prefixed with webkit. It provides a random bit generator, and a number of cryptographic primitives invoked via a complex asynchronous interface. The cryptographic primitives include two RSA signature schemes, RSASSA-PSS and RSASSA-PKCS1-v1_5 (described in RFC 3447), and ECDSA with NIST curves P-256, P-384 and P-512 (described, e.g., in the ECDSA Certicom white paper). Other primitives include ECDH, AES (including AES-GCM), HMAC, SHA (including SHA-1, SHA-256, SHA-384 and SHA-512), HKDF and PBKDF2. Surprisingly, DSA is not included.

In the Web Cryptography API, generation of an RSA or ECDSA key pair produces two CryptoKey objects, one containing the private key, the other containing the public key. When the key pair is generated, the private key can be made non-extractable from its CryptoKey object. This means that it cannot later be extracted from the object by JavaScript code embedded in a Web page, even if that Web page has the same origin as the Web page containing the JavaScript code that invoked the key generation procedure. A CryptoKey object is not persistent by itself, and it is not an ordinary JavaScript object that could be encoded as a string for storage in localStorage, but it can be stored in a database accessed through the IndexedDB API.

Slide 8: The Service Worker API

The Service Worker API is a crucial web technology that allows the front-end of a web app to work “offline”, without communicating with the back-end. Besides its usage in connection with key storage, it has the potential to allow apps to become fully competitive with native apps, without requiring app installation. It is available in Chrome, Firefox and Opera, under development in Edge, and under consideration for Safari.

Here is how it works: the JavaScript front-end of the web application registers a service worker with the browser, and configures it to intercept certain requests to the back-end. The service worker can handle an intercepted request by generating a Web page on the fly and delivering it to the browser, which renders it as if it came from the back-end. The generated page may include JavaScript code, which can retrieve a cryptographic credential from persistent browser storage and present it to a verifier.

Slide 9: Two combinations of web technologies

The table in Slide 9 has entries to be filled in with four solutions for storing cryptographic keys, or more specifically cryptographic credentials, in persistent browser storage. The entries are filled in in Slide 19 after describing the first solution in Slides 10-18.

The two columns of the table refer to two possible combinations of the new web technologies.

The first column refers to the combination of localStorage for storing a credential with the Service Worker API for presenting the credential as described below. This combination supports the storage and presentation of any kind of cryptographic credential, including traditional certified key pairs, but also anonymous credentials such as Idemix (now available on Github from IBM) or rich credentials.

The second column refers the combination of the IndexedDB API for storing a credential with the Web Cryptography API for wrapping a private key in a CryptoKey object and the Service Worker API for presenting the credential. It only supports credentials based on RSA or ECDSA key pairs, but the private key can be made non-extractable by JavaScript code from its CryptoKey object.

The meaning of the two rows is described below in connection with Slide 19, after Solution 1 is described in Slides 10-18.

Slides 10-13: issuance of a cryptographic credential in Solution 1

Slides 10-13 are an animation that illustrates the issuance of a cryptographic credential and its storage in localStorage in Solution 1.

In Slide 10 the user visits the Web site of the credential issuer and downloads a credential issuance web page with embedded JavaScript code, which comprise the front-end of the credential issuance application.

In Slide 11 the front-end of the issuance application, or more specifically the embedded JavaScript code, executes an issuance protocol with the back-end of the application. In the simple case where the credential is a certified key pair, this means that: (i) the front-end generates a key pair; (ii) the front-end sends a certificate signing request to the back-end of the issuance application, comprising the public key component of the key pair and a proof of knowledge of the associated private key; (iii) the back-end signs a certificate binding the public key to attributes of the user and metadata; and (iv) the back-end sends the certificate to the front-end.

In Slide 12 the JavaScript front-end of the issuance application stores the cryptographic credential in localStorage.

In Slide 13 the JavaScript front-end registers a service worker with the browser and configures it to intercept credential presentation requests.

Slides 14-18: presentation of a cryptographic credential in Solution 1

Slides 14-18 are an animation that illustrates the presentation of a cryptographic credential in Solution 1.

In Slide 14 the user visits a web site that requires presentation of the credential in order for the user to identify him/herself or demonstrate possession or one or more attributes certified by the credential. (If the credential supports selective disclosure, as anonymous credentials and rich credentials do, the user may only need to disclose the attributes required by the verifier rather than disclosing all the attributes included in the credential.) This web site is called here the credential verifier, and could also be referred to as the relying party.

In Slide 15 the user clicks a button on a verifier web page, thus sending an HTTP request that the verifier redirects to the credential issuer, exactly as in a federated login protocol such as a login with Facebook or Twitter. However, whereas in federated login the identity provider has to be online and involved in each login (a tough availability and performance requirement) and therefore observes each login (a serious privacy drawback), here the redirected request is intercepted by the service worker and never seen by the back-end of the issuer. If the credential supports selective disclosure, the redirected request also specifies the attributes required by the verifier.

In Slide 16 the service worker generates a web page on the fly that asks the user for consent to present the credential. If the credential supports selective disclosure, the consent request page also asks the user for permission to disclose the required attributes to the verifier.

In Slide 17 JavaScript code embedded in the consent request page retrieves the credential from localStorage. It can do so because it has the same origin as the JavaScript code that stored the credential in Slide 12.

In Slide 18 the JavaScript code embedded in the consent request page executes a credential presentation protocol with the verifier.

In the simple case of a certified key pair, the presentation protocol consists of sending the certificate and proving knowledge of the associated private key.

In the case of a credential that supports selective disclosure, only those attributes required by the verifier are disclosed.

In the case of an anonymous credential, such as Idemix, that provides multishow and issue-show unlinkability in addition to selective disclosure, multiple presentations cannot be linked to each other or to issuance.

A rich credential, besides supporting selective disclosure, also supports presentation of multiple verification factors, including proof of knowledge of a password and proof of possession of one or more biometric traits in addition to proof of knowledge of a private key. Furthermore, it supports selective presentation of those factors. Therefore, if the credential is a rich credential: (i) the presentation protocol may include submission of a biometric sample, with presentation attack detection by the verifier; (ii) in the redirected request the verifier may specify the factors to be presented in addition to specifying the attributes to be disclosed; and (iii) the consent request page may ask the user for permission to present the required factors in addition to requesting permission to disclose the required attributes.

Slide 19: Three other solutions

In Solution 2 the cryptographic credential is a certified key pair. The JavaScript front-end of the issuance application uses the Web Cryptography API to generate the key pair, and makes the private key unextractable from its CryptoKey object. Because a CryptoKey object cannot be converted to a JavaScript string, the credential is stored in a database by means of the IndexedDB API.

Solutions 3 and 4 make use of a trusted consent manager, assumed to be honest and secure, which provides a Web application whose front-end performs the functions performed by the issuer front-end in Solutions 1 and 2. The JavaScript front-end of the consent manager executes the credential issuance protocol with the back-end of the issuer, stores the credential, and registers the service worker, which later requests the user’s consent and presents the credential to the verifier.

Slides 20-26: comparative security postures

Slides 20-26 show a table that compares the security postures of the four solutions of Slide 19 to other methods of storing a cryptographic credential. The slides refer to the user as the “subject” because the table is concerned with a credential issued to the user. The rows in the table refer to storage methods while the columns refer to attacks. As explained in the overlay of Slide 20 that goes away in Slide 21, each entry in the table is labeled “Capture” if the corresponding attack succeeds in capturing the credential, or “Use” if the attack succeeds in using the credential on the subject’s computing device but cannot extract it for use on another device, or “Secure” if the attack does not succeed in capturing or using the credential.

The first two rows of the table refer to Solutions 1 and 2. The third row refers to Solutions 3 and 4, which rely on a trusted consent manager; no distinction is made between those two solutions because the trusted consent manager is assumed to be honest and secure. The next three rows are concerned with storing the credential in a smart card. In the fourth row, the credential is provided to the subject by the credential issuer with a preloaded credential. In the fifth row, the credential is generated in the smartcard after the smartcard has been provided to the subject by the issuer; e.g., if the credential is a certified key pair, the key pair is generated on the card, then the public key is certified by the issuer and the resulting certificate is imported into the card. In the sixth row the credential is generated on a card that the subject obtains from a trusted card manufacturer, so that credential generation is performed by trusted firmware. In the last two rows the credential is stored in secure hardware embedded within the subject’s device, either tamper-proof hardware such as a secure element or a TPM, or a Trusted Execution Environment that provides protection against malware but not necessarily against physical tampering.

The first column refers to an attack by a malicious or compromised issuer at the time when the credential is issued. The second column refers to an attack that originates from the issuer’s web site after the credential has been issued. The attack may take place after the issuer has been compromised or infiltrated by a malicious actor, or it may be carried out by an adversary who exploits a vulnerability in the issuer’s web site, such as a cross-site scripting (XSS) vulnerability. The purpose of the third column is to illustrate the fact that JavaScript code with a Web origin other than the issuer’s, i.e. embedded in a Web page downloaded by the subject from a DNS domain other than the domain of the credential issuance application, cannot be used to capture or use the credential; all entries in that column are labeled “Secure”. The fourth column refers to an attack by malware, which is assumed to have taken complete control of the subject’s computing device. The last column refers to an attack by an adversary who physically captures the subject’s device and is able to access all storage not contained in tamper-proof hardware.

Slides 22-26 highlight a few observations that can be made by examining the entries in the table.

Slide 22 highlights the fact that the four solutions of Slide 19 are secure against attacks by malicious JavaScript having a Web origin other than the domain of the credential issuance application. This implies that they are secure under the assumptions that the issuer is honest and secure, that there is no malware on the subject’s device, and that the adversary does not physically capture the subject’s device. (As already mentioned above, in the case of Solutions 3 and 4, there is also an assumption that the trusted consent manager is honest and secure.)

Slide 23 highlights the fact that the four solutions of Slide 19 are not secure against malware on the subject’s device or physical capture of the device.

Slide 24 highlights the fact that the four solutions of Slide 19 have different security postures against attacks that originate from the issuer after the credential has been issued. In Solution 1, malicious JavaScript code of same Web origin as the credential issuance application can retrieve the credential from localStorage, including the private key if the credential is a certified key pair, and deliver it to the adversary for use on any device. In Solution 2, malicious JavaScript code of same Web origin as the credential issuance application can retrieve the credential, which is an RSA or ECDSA certified key pair, from the IndexedDB database where it is stored, and use it by means of the Web Cryptography API, but it cannot extract the private key from its CryptoKey object for use on a different device, nor transfer the CryptoKey object itself to a different device. In Solutions 3 and 4, JavaScript from an origin other than the domain of the trusted consent manager cannot access the credential; hence, assuming that the consent manager does not share a DNS domain with the issuer, Solutions 3 and 4 are secure against attacks that originate from the issuer after the credential has been issued.

Slide 25 highlights the fact localStorage may be more secure than smartcard storage under certain assumptions. Specifically, if it can be assumed that the subject’s device is free of malware and is not captured by the adversary, then Solution 3, where a trusted consent manager, assumed to be honest and secure, stores the credential in localStorage, is secure. By contrast, credential storage in a smartcard provided by the issuer is not secure against an issuer-originated attack at issuance, even if the credential is a certified key pair and key pair generation takes place on the card. This is because a malicious or compromised issuer may have installed malicious firmware on the card before delivering it to the subject. Smartcard security requires trusted firmware, which in turn requires that the subject obtain the smartcard directly from a trusted manufacturer rather than from the issuer, if the issuer is not fully trusted. Thus a trusted card manufacturer plays a role in smartcard credential storage analogous to that of a trusted consent manager in browser storage.

Finally, Slide 26 highlights the fact that secure hardware embedded in the subject’s device, either tamper-proof hardware or a TEE, provide good security. Unfortunately, such credential storage solutions cannot be used today by developers of Web applications. We heard at the conference, however, that GlobalPlatform may be working on making credential storage in a TEE available to Web applications.

Slide 27: Potential applications

Most of the talk has focused on the storage of cryptographic credentials, which can be used for remote identity proofing, recurring authentication, or privilege escalation. But persistent browser storage can also be used for storing cryptographic keys used for other purposes.

One possible application is end-to-end encrypted Web mail. Secure messaging is becoming popular, but at this time it requires either a native email client that supports S/MIME, or a native app that implements ad-hoc encrypted messaging. Web mail is a Web application. Messages are stored in a server, but are composed and read in the browser. End-to-end encryption would require the messages to be encrypted in the sender’s browser, and decrypted in the recipient’s browser using the recipient’s private key. The above solutions could be adapted to store the private key used to decrypt messages in the recipient’s browser together with the associated certificate, as well as the private key used for signing messages in the sender’s browser with its associated certificate.

Another possible application would be cryptographically secured online payments.

2 thoughts on “Storing Cryptographic Keys in Persistent Browser Storage”

    1. Good question. A trusted consent manager allows the user to specify his/her consent to present particular credentials to particular verifiers (a.k.a. relying parties), or to disclose particular attributes of selective disclosure credentials, at transaction time or during configuration. The concept was introduced in a fedetated identity management context. I believe it was used by Shibboleth in the InCommon Federation. Ken Klingestein of Internet2 gave a talk about it at IIW.

      The main benefit of a trusted consent manager is that it improves the user experience by centralizing in a unified framework with a common user interface the consent management for any number of issuers and any number of verifiers.

      In the talk referenced by the blog post, the JavaScript front-end of the TCM is issued credentials from the issuers, keeps them in browser storage where they can only be accessed by JS codde of same web origin as the TCM, and uses its own service worker to ask for consent and present each credential (or, more precisely, to construct a page that does that). Without a TCM, it is the front-end of each issuer that is issued each credential and registers a service worker to ask for consent and present the credential. Besides the user experience improvement, a TCM provides security posture benefits that are highlighted in slides 24-25.

Leave a Reply

Your email address will not be published.