Keygen and Client Certificates

W3C Working Draft,

This version:
GitHub w3ctag/client-certificates (file an issue; open issues)


The TAG considers the HTML <keygen> element and its use cases; related security issues are also reviewed and requirements and a recommendation to replace <keygen> is presented.

Status of this document

This document has been produced by the W3C Technical Architecture Group (TAG). This document is a work in progress and represents the rough consensus of the TAG.

Table of Contents

1. <keygen> and use cases

The HTMLKeygenElement [HTML5] enables web sites to generate a public/private key pair during form submission (see also Public Key Cryptography). <keygen> is a browser feature grandfathered into the HTML5 specification. This element is a form-associated element with UI, but does not expose its generated private key to JavaScript. (Note: a Service Worker [service-workers] may be able to retrieve the public key from a form submission request.) The private key is stored in a secured browser-managed or OS-managed key store on behalf of the user.

The primary use case for <keygen> is to establish a trusted identity for an individual; the identity can later be used to authenticate to a web site or set of web sites. Because it uses an identity tied to a private key, authentication is fundamentally more secure than systems which use shared passwords.

Extending the above use case, <keygen> is commonly the first stage in provisioning a user’s device to receive a client certificate. For example, <keygen> is used to generate the key material for later inclusion in an X509 certificate. The certificate is intended to be long-lived and may serve to authenticate wireless accounts, educational portals, internal business intranets, etc.

Sequence diagram showing how keygen provisions a client certificate.

The diagram above describes a typical scenario in which the <keygen> element is used for provisioning a client certificate.

  1. The user agent navigates to a provisioning site (at a specific origin). The HTML resource containing the keygen element with optional challenge attribute is received by the user agent. The keygen element is included in a form intended to be submitted back to the server.

  2. The user may select from among two options in the keygen element’s UI to choose a "weak" or "strong" key length.

  3. The user submits the form. Alternately, JavaScript code in the user agent can submit the form. When submitted the keygen element causes an asymmetric key pair to be generated: a public and private key. These keys are not exposed via a DOM API (although the public key may be retrieved from the form in an installed Service Worker).

  4. The private key is used to optionally sign a challenge and then it is placed into a secure key store (either browser or OS-provided).

  5. The public key is encoded (ASN.1 DER) and submitted in the form to the server.

  6. In the POST response, the server may have packaged the public key and other related information into a client certificate which is sent with an application/x-x509-*-cert mimetype to the user agent. The user agent relays this certificate into the user’s certificate store for later use.

2. Client certificates and user agents

Keygen is one way to generate the crypto material needed for a client certificate in the browser (the Web Crypto API [webcryptoapi] provides another--though it has drawbacks described later). Once a client certificate has been issued and registered with the user agent (either via a browser or OS-supplied certificate store), the certificate may be used for authentication. This is relatively uncommon; when it does happen, user agents do not provide a good experience.

A server can require a TLS client certificate to be used when it receives a request for a protected resource. The server may also include a challenge to be signed by the client as proof that the user has possession of the private key associated with the public key in the client certificate. Starting with the server’s response to the protected resource request, the experience typically follows this pattern:

  1. The user agent asks the user to select a client certificate to use in the negotiation (there may be more than one). One or more client certificates are presented to the user. Little effort is made to differentiate or extract meaningful information from each certificate in order to help the user select the right one. The user chooses a certificate.

  2. [Typically] a second prompt (issuing from the secure keystore) is presented to confirm and approve use of a private key in order to perform a signature (for the challenge). Unfortunately, little context is actually provided in the message presented to the user, making it unclear why and for what purpose the private key is being accessed.

  3. The signed challenge and client certificate are sent to the server for verification to release the resource.

Note: The ability to use client certificates for authentication is currently not allowed in the HTTP2 protocol (it requires an older TLS re-negotiation protocol). The IETF is investigating how to improve support for client certificate authentication in HTTP2.

3. Threat Model

User agents are now considering removing support for the <keygen> element due (in part) to security issues present in its design and implementation. The following threat model frames these issues.

The trust boundaries in the threat model separate the user agent and server, as well as the user agent and secure keystore.

3.1. User agent/server boundary

This trust boundary may be either protected via an HTTPS connection, or open using an untrusted link. The keygen element is not currently considered a "powerful feature" and thus it works in both insecure and secure contexts [powerful-features]. (Keygen would certainly be considered a powerful feature by today’s standards.) When using an insecure connection, the content provided by the server cannot be trusted, including the behavior of script from that resource.

3.2. User agent/secure keystore boundary

Some user agents defer to their host OS to manage and secure crypto key material (an alternative, e.g., in Mozilla Firefox, is to have a browser-provided keystore). For host OS-managed cases, a trust boundary exists between the user agent and the OS (data that flows across this boundary is generally implicitly trusted). The risk to user agents relying on an OS-provided keystore is that changes to the keystore have a global impact on the user’s device. This is particularly dangerous if keystore changes happen without user-consent and automatically by script. Since the host OS’s keystore is a shared resource, all apps are put at risk. Of course, when the browser implements its own keystore, the risk to the OS and other applications is mitigated.

3.3. Known Threats

  1. Untrusted script can launch denial-of-service attacks against the user’s keystore, since form submission (including keygen) does not require user action.

  2. Keygen form submission has unmitigated access to the keystore; script can affect either 1) global OS state changes without user permission, or 2) origin-unaware certificate installation (in user agents that implement their own keystore). At a minimum, this violates the same origin policy.

  3. While not specifically impacting keygen, user agents may automatically install client certificates via a special mime-type. As noted, this can affect state outside the boundary of the browser sandbox without user permission.

4. Principles

5. Replacing <keygen>

The keygen element should be replaced by a new API better suited for modern day application requirements. While keygen can conceivably be updated in some ways improve its hashing algorithm and container formats, for example, its function as an element tied to form submission locks it into a specific declarative protocol. While convenient in some respects, it is also limiting in that it is not very extensible, cannot be applied in scenarios outside of its protocol (e.g., outside of form submission scenarios), and isn’t designed with user-permission in mind. We believe keygen isn’t suitable for updating in its existing form; rather we think starting over with a new API untethered from the past has the better potential to succeed. In order to better understand the requirements for an API intended to replace keygen, we first consider where it is weak and what improvements should be made to meet modern requirements.

Additionally, any installation of a client certificate (e.g., the application/x-x509-*-cert mimetype) must also require user consent.

In seeking for a replacement to keygen, we also consider what capabilities are already provided by the Web Crypto API:

Unfortunately, the current capabilities in the Web Crypto API are unsuitable as a direct-replacement for keygen because:

However, the objects and abstractions defined in the Web Crypto API are a good foundation on which to design a replacement for keygen. We note that provisioning of keys is currently declared out-of-scope in the current Web Crypto API spec. New work on a keygen replacement would have key provisioning in scope.

6. Requirements and Recommendations

In order to replace keygen and simultaneously provide a better way for establishing a trusted identity on the web, we recognize the following requirements. The solution:

Given these requirements, we recognize that an "improved keygen element" could be built using the new solution as a foundation (e.g., using web components).

We also call on implementations to improve the client certificate UI experience in order to make client-certificate use in authentication more accessible to general users.


Informative References

Ryan Sleevi; Mark Watson. Web Cryptography API. 11 December 2014. CR. URL:
Ian Hickson; et al. HTML5. 28 October 2014. REC. URL:
Mike West; Yan Zhu. Privileged Contexts. 24 April 2015. WD. URL:
Alex Russell; Jungkee Song; Jake Archibald. Service Workers. 25 June 2015. WD. URL: