W3C

Web Cryptography API

W3C Working Draft 25 June 2013

This Version:
http://www.w3.org/TR/2013/WD-WebCryptoAPI-20130625/
Latest Published Version:
http://www.w3.org/TR/WebCryptoAPI/
Latest Editor’s Draft:
http://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html
Previous Versions:
http://www.w3.org/TR/2013/WD-WebCryptoAPI-20130108/
http://www.w3.org/TR/2012/WD-WebCryptoAPI-20120913/
Editors:
David Dahl, Mozilla Corporation <ddahl@mozilla.com>
Ryan Sleevi, Google, Inc. <sleevi@google.com>
Participate:

Send feedback to public-webcrypto-comments@w3.org (archives), or file a bug (see existing bugs).


Abstract

This specification describes a JavaScript API for performing basic cryptographic operations in web applications, such as hashing, signature generation and verification, and encryption and decryption. Additionally, it describes an API for applications to generate and/or manage the keying material necessary to perform these operations. Uses for this API range from user or service authentication, document or code signing, and the confidentiality and integrity of communications.

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document is the 25 June 2013 Working Draft of the Web Cryptography API specification. Please send comments about this document to public-webcrypto-comments@w3.org (archived).

This document is produced by the Web Cryptography WG of the W3C.

Implementors should be aware that this specification is not stable. Implementors who are not taking part in the discussions are likely to find the specification changing out from under them in incompatible ways. Vendors interested in implementing this specification before it eventually reaches the Candidate Recommendation stage should join the mailing lists that follow and take part in the discussions.

The Web Cryptography Working Group invites discussion and feedback on this draft document by web developers, companies, standardization bodies or forums interested in deployment of secure services with web applications. Specifically, Web Cryptography Working Group is looking for feedback on:

Previous discussion of this specification has taken place on three other mailing lists: whatwg@whatwg.org (archive) , public-websecurity@w3.org (archive), and public-identity@w3.org (archive). Ongoing discussion will be on the public-webcrypto@w3.org mailing list.

Web content and browser developers are encouraged to review this draft. Please send comments to public-webcrypto-comments@w3.org, the W3C's public email list for issues related to Web Cryptography. Archives of the public list and archives of the member's-only list are available.

Changes made to this document can be found in the W3C public Mercurial server.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents

1. Introduction

This section is non-normative.

The Web Cryptography API defines a low-level interface to interacting with cryptographic key material that is managed or exposed by user agents. The API itself is agnostic of the underlying implementation of key storage, but provides a common set of interfaces that allow rich web applications to perform operations such as signature generation and verification, hashing and verification, encryption and decryption, without requiring access to the raw keying material.

Cryptographic transformations are exposed via the CryptoOperation interface, which defines a common set of methods and events for dealing with initialization, processing data, and completing the operation to yield the final output. In addition to operations such as signature generation and verification, hashing and verification, and encryption and decryption, the API provides interfaces for key generation, key derivation, key import and export, and key discovery.

2. Use Cases

This section is non-normative

2.1. Multi-factor Authentication

A web application may wish to extend or replace existing username/password based authentication schemes with authentication methods based on proving that the user has access to some secret keying material. Rather than using transport-layer authentication, such as TLS client certificates, the web application may wish to provide a rich user experience by providing authentication within the application itself.

Using the Web Cryptography API, such an application could locate suitable client keys, which may have been previously generated via the user agent or pre-provisioned out-of-band by the web application. It could then perform cryptographic operations such as decrypting an authentication challenge followed by signing an authentication response.

Further, the authentication data could be further enhanced by binding the authentication to the TLS session that the client is authenticating over, by deriving a key based on properties of the underlying transport.

If a user did not already have a key associated with their account, the web application could direct the user agent to either generate a new key or to re-use an existing key of the user's choosing.

2.2. Protected Document Exchange

When exchanging documents that may contain sensitive or personal information, a web application may wish to ensure that only certain users can view the documents, even after they have been securely received, such as over TLS. One way that a web application can do so is by encrypting the documents with a secret key, and then wrapping that key with the public keys associated with authorized users.

When a user agent navigates to such a web application, the application may send the encrypted form of the document. The user agent is then instructed to unwrap the encryption key, using the user's private key, and from there, decrypt and display the document.

2.3. Cloud Storage

When storing data with remote service providers, users may wish to protect the confidentiality of their documents and data prior to uploading them. The Web Cryptography API allows an application to have a user select a private or secret key, to either derive encryption keys from the selected key or to directly encrypt documents using this key, and then to upload the transformed/encrypted data to the service provider using existing APIs.

This use case is similar to the Protected Document Exchange use case because Cloud Storage can be considered as a user exchanging protected data with himself in the future.

2.4. Document Signing

A web application may wish to accept electronic signatures on documents, in lieu of requiring physical signatures. An authorized signature may use a key that was pre-provisioned out-of-band by the web application, or it may be using a key that the client generated specifically for the web application.

The web application must be able to locate any appropriate keys for signatures, then direct the user to perform a signing operation over some data, as proof that they accept the document.

2.5. Data Integrity Protection

When caching data locally, an application may wish to ensure that this data cannot be modified in an offline attack. In such a case, the server may sign the data that it intends the client to cache, with a private key held by the server. The web application that subsequently uses this cached data may contain a public key that enables it to validate that the cache contents have not been modified by anyone else.

2.6. Secure Messaging

In addition to a number of web applications already offering chat based services, the rise of WebSockets and RTCWEB allows a great degree of flexibility in inter-user-agent messaging. While TLS/DTLS may be used to protect messages to web applications, users may wish to directly secure messages using schemes such as off-the-record (OTR) messaging.

The Web Cryptography API enables OTR, by allowing key agreement to be performed so that the two parties can negotiate shared encryption keys and message authentication code (MAC) keys, to allow encryption and decryption of messages, and to prevent tampering of messages through the MACs.

2.7. Javascript Object Signing and Encryption (JOSE)

A web application wishes to make use of the structures and format of messages defined by the IETF Javascript Object Signing and Encryption (JOSE) Working Group. The web application wishes to manipulate public keys encoded in the JSON key format (JWK), messages that have been integrity protected using digital signatures or MACs (JWS), or that have been encrypted (JWE).

3. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, RECOMMENDED, MAY, OPTIONAL, in this specification are to be interpreted as described in Key words for use in RFCs to Indicate Requirement Levels [RFC2119].

The following conformance classes are defined by this specification:

conforming user agent

A user agent is considered to be a conforming user agent if it satisfies all of the MUST-, REQUIRED- and SHALL-level criteria in this specification that apply to implementations. This specification uses both the terms "conforming user agent" and "user agent" to refer to this product class.

User agents MAY implement algorithms in this specification in any way desired, so long as the end result is indistinguishable from the result that would be obtained from the specification's algorithms.

User agents that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [WEBIDL] as this specification uses that specification and terminology.

4. Scope

This section is non-normative.

4.1. Level of abstraction

The specification attempts to focus on the common functionality and features between various platform-specific or standardized cryptographic APIs, and avoid features and functionality that are specific to one or two implementations. As such this API allows key generation, management, and exchange with a level of abstraction that avoids developers needing to care about the implementation of the underlying key storage. The API is focused specifically around Key objects, as an abstraction for the underlying raw cryptographic keying material. The intent behind this is to allow an API that is generic enough to allow conforming user agents to expose keys that are stored and managed directly by the user agent, that may be stored or managed using isolated storage APIs such as per-user key stores provided by some operating systems, or within key storage devices such as secure elements, while allowing rich web applications to manipulate the keys and without requiring the web application be aware of the nature of the underlying key storage.

4.2. Cryptographic algorithms

Because the underlying cryptographic implementations will vary between conforming user agents, and may be subject to local policy, including but not limited to concerns such as government or industry regulation, security best practices, intellectual property concerns, and constrained operational environments, this specification does not dictate a mandatory set of algorithms that MUST be implemented. Instead, it defines a common set of bindings that can be used in an algorithm-independent manner, a common framework for discovering if a user agent or key handle supports the underlying algorithm, and a set of conformance requirements for the behaviours of individual algorithms, if implemented.

4.3. Operations

Although the API does not expose the notion of cryptographic providers or modules, each key is internally bound to a cryptographic provider or module, so web applications can rest assured that the right cryptographic provider or module will be used to perform cryptographic operations involving that key.

4.4. Out of scope

This API, while allowing applications to generate, retrieve, and manipulate keying material, does not specifically address the provisioning of keys in particular types of key storage, such as secure elements or smart cards. This is due to such provisioning operations often being burdened with vendor-specific details that make defining a vendor-agnostic interface an unsuitably unbounded task. Additionally, this API does not deal with or address the discovery of cryptographic modules, as such concepts are dependent upon the underlying user agent and are not concepts that are portable between common operating systems, cryptographic libraries, and implementations.

5. Security considerations

This section is non-normative.

5.1. Security considerations for implementers

User agents should take care before exposing keys that were not explicitly generated via the API in this specification or exposing keys that were generated in the context of other origins. Two applications with access to the same key handle may be able to spoof messages to each other, as both valid and hostile messages will appear to be valid for the given key. Because of this, user agents are recommended to obtain express permission from the user before re-using keys, unless there is a prearranged trust relationship.

User agents should be aware of the security considerations of each algorithm implemented and exposed to applications. For a number of algorithms, their cryptographic strength is relative to the amount of work necessary to compute the result, whether this be through the generation of significantly large prime numbers or through the repeatedly iterating through the same algorithm to reduce its susceptibility to brute force. Implementations should therefore take measures to ensure against misuse. Such measures may include requiring express user permission to compute some expensive operations, rate limiting the number of times the application may call certain APIs/algorithms, and defining implementation-specific upper limits for inputs such as key sizes or iteration counts, as appropriate for the device on which the implementation executes.

In some cases, the same underlying cryptographic key material may be re-usable for multiple algorithms. One such example is an RSA key, which may be used for both signing and encryption, or with RSA-PKCS1v1.5 and RSA-PSS. In some cases, the re-use of this key material may undermine the security properties of the key and allow applications to recover the raw material.

Editorial note
  • ISSUE-33 One proposed technical solution for user agents is to implement "key tainting", in which it records how a particular key has been used (eg: algorithms, parameters), and prevents it from being re-used in a manner that is unsafe or contrary to the security - such as preventing a PKCS1-v1.5 key from being used with RSA-PSS, or preventing an RSA-OAEP w/ MGF1-SHA1 from being used with RSA-OAEP w/ MGF1-SHA256. Questions exist about whether this should be encouraged or permitted, and the interoperability concerns it might cause.

5.2. Security considerations for developers

While this API provides important functionality for the development of secure applications, it does not try to address all of the issues that may arise from the web security model. As such, application developers must take care to ensure against common attacks such as script injection by making use of appropriate security functionality such as Content Security Policy and the use of TLS.

This API includes a variety of cryptographic operations, some of which may have known security issues when used inappropriately. Application developers should take care to review the appropriate cryptographic literature before making use of certain algorithms, and should avoid attempting to develop new cryptographic protocols whenever possible.

While the API in this specification provides a means to protect keys from future access by web applications, it makes no statements as to how the actual keying material will be stored by an implementation. As such, although a key may be inaccessible to web content, it should not be presumed that it is inaccessible to end-users. For example, a conforming user agent may choose to implement key storage by storing key material in plain text on device storage. Although the user agent prevents access to the raw keying material to web applications, any user with access to device storage may be able to recover the key.

6. Privacy considerations

This section is non-normative.

Fingerprinting
Malicious applications may be able to fingerprint users or user agents by detecting or enumerating the list of algorithms that are supported. This is especially true if an implementation exposes details about users' smart cards or secure element storage, as the combination of algorithms supported by such devices may be used to fingerprint devices more accurately than just the particular user agent.
Tracking
If user agents permit keys to be re-used between origins, without performing any secondary operations such as key derivation that includes the origin, then it may be possible for two origins to collude and track a unique user by recording their ability to access a common key.
Super-cookies
With the exception of ephemeral keys, its often desirable for applications to strongly associate users with keys. These associations may be used to enhance the security of authenticating to the application, such as using a key stored in a secure element as a second factor, or may be used by users to assert some identity, such as an e-mail signing identity. As such, these keys often live longer than their counterparts such as usernames and passwords, and it may be undesirable or prohibitive for users to revoke these keys. Because of this, keys may exist longer than the lifetime of the browsing context [HTML] and beyond the lifetime of items such as cookies, thus presenting a risk that a user may be tracked even after clearing such data. This is especially true for keys that were pre-provisioned for particular origins and for which no user interaction was provided.

7. Dependencies

This specification relies on underlying specifications.

DOM

A conforming user agent MUST support at least the subset of the functionality defined in DOM4 that this specification relies upon; in particular, it MUST support Promises. [DOM4]

HTML

A conforming user agent MUST support at least the subset of the functionality defined in HTML that this specification relies upon; in particular, it MUST support event loops and event handler IDL attributes. [HTML]

Web IDL

A conforming user agent MUST be a conforming implementation of the IDL fragments in this specification, as described in the Web IDL specification. [WebIDL]

Typed Arrays

A conforming user agent MUST support the Typed Arrays specification [TypedArrays].

8. Terminology

The terms and algorithms document, event handler IDL attributes, event handler event type, origin, same origin, URL, event loops, task, task source, queue a task, fire a simple event, and structured clone, are defined by the HTML specification [HTML].

When this specification says to terminate the algorithm, the user agent must terminate the algorithm after finishing the step it is on. The algorithm referred to is the set of specification-defined processing steps, rather than the underlying cryptographic algorithm that may be in the midst of processing.

9. RandomSource interface

IDL

[NoInterfaceObject]
interface RandomSource {
  ArrayBufferView getRandomValues(ArrayBufferView array);
};
        

9.1. Description

The RandomSource interface represents an interface to a cryptographically strong pseudo-random number generator seeded with truly random values.

Implementation note: Implementations should generate cryptographically random values using well-established cryptographic pseudo-random number generators seeded with high-quality entropy, such as from an operating-system entropy source (e.g., "/dev/urandom"). This specification provides no lower-bound on the information theoretic entropy present in cryptographically random values, but implementations should make a best effort to provide as much entropy as practicable.

Implementation note: This interface defines a synchronous method for obtaining cryptographically random values. While some devices and implementations may support truly random cryptographic number generators or provide interfaces that block when there is insufficient entropy, implementations are encouraged not to use these sources when implementing getRandomValues, both for performance and to avoid depleting the system of entropy. Instead, these sources should be used to seed a cryptographic pseudo-random number generator that can then return suitable values efficiently.

9.2. Methods and Parameters

9.2.1. The getRandomValues method

The getRandomValues method generates cryptographically random values. It must act as follows:

  1. If array is not of an integer type (i.e., Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, or Uint32Array), throw a TypeMismatchError and terminate the algorithm.

  2. If the byteLength of array is greater than 65536, throw a QuotaExceededError and terminate the algorithm.

  3. Overwrite all elements of array with cryptographically random values of the appropriate type.

  4. Return array.

Note

Do not generate keys using the getRandomValues method. Use the generateKey method instead.

10. Algorithm dictionary

The Algorithm object is a dictionary object [WebIDL] which is used to specify an algorithm and any additional parameters required to fully specify the desired operation.

IDL

// TBD: ISSUE-28
typedef (Algorithm or DOMString) AlgorithmIdentifier;

dictionary Algorithm {
  DOMString name;
};
        

10.1. Algorithm Dictionary Members

name
The name of the registered algorithm to use.

11. Key interface

The Key object represents an opaque reference to keying material that is managed by the user agent.

IDL

enum KeyType {
  "secret",
  "public",
  "private"
};

enum KeyUsage {
  "encrypt",
  "decrypt",
  "sign",
  "verify",
  "derive",
  "wrap",
  "unwrap"
};

interface Key {
  readonly attribute KeyType type;
  readonly attribute bool extractable;
  readonly attribute Algorithm algorithm;
  readonly attribute KeyUsage[] keyUsage;
};
        

11.1. Description

This section is non-normative

This specification provides a uniform interface for many different kinds of keying material managed by the user agent. This may include keys that have been generated by the user agent, derived from other keys by the user agent, imported to the user agent through user actions or using this API, pre-provisioned within software or hardware to which the user agent has access or made available to the user agent in other ways. The term key refers broadly to any keying material including actual keys for cryptographic operations and secret values obtained within key derivation or exchange operations.

The Key object is not required to directly interface with the underlying key storage mechanism, and may instead simply be a reference for the user agent to understand how to obtain the keying material when needed, eg. when performing a CryptoOperation.

11.2. Key interface members

type
The type of the underlying key. Opaque keying material, including that used for symmetric algorithms, is represented by "secret", while keys used as part of asymmetric algorithms composed of public/private keypairs will be either "public" or "private".
extractable
Whether or not the raw keying material may be exported by the application.
algorithm
The Algorithm used to generate the key.
keyUsage
An Array of KeyUsages that indicate what CryptoOperations may be used with this key.

11.3. Structured clone algorithm

When a user agent is required to obtain a structured clone of a Key object, it must run the following steps.

  1. Let input and memory be the corresponding inputs defined by the internal structured cloning algorithm, where input represents a Key object to be cloned.
  2. Let output be a newly constructed Key object.
  3. Let the following attributes of output be equal to the value obtained by invoking the internal structured clone algorithm recursively, using the corresponding attribute on input as the new "input" argument and memory as the new "memory" argument:
  4. Let output refer to the same underlying cryptographic material and cryptographic material key storage of input.
Note
Implementation Note: When performing the structured clone algorithm for a Key object, it is important that the underlying cryptographic key material not be exposed to a JavaScript implementation. Such a situation may arise if an implementation fails to implement the structured clone algorithm correctly, such as by allowing a Key object to be serialized as part of a structured clone implementation, but then deserializing it as a DOMString, rather than as a Key object.

12. CryptoOperation interface

IDL

interface CryptoOperation : Promise {
  CryptoOperation process(ArrayBufferView buffer);
  CryptoOperation finish();
  CryptoOperation abort();

  readonly attribute Key? key;
  readonly attribute Algorithm algorithm;
};
        

12.1. Processing Model

Every CryptoOperation is said to have an associated resolver, an internal state, an associated algorithm, an internal count of available bytes, and a list of pending data.

Each object in the list of pending data represents data that should undergo the associated cryptographic transformation. The order in which items are added to the list shall be reflected in the order in which items are processed, with the first item added being the first item processed.

When a CryptoOperation is said to process data, the user agent must execute the following algorithm:

  1. If the list of pending data contains no items, terminate the algorithm.

  2. If the underlying implementation does not support multi-part cryptographic operations for the associated algorithm:
    1. Let bytes be an empty sequence of bytes.

    2. For each item in the list of pending data:

      1. Let item be the oldest remaining item in the list of pending data.

      2. Remove item from the list of pending data.

      3. Convert item to a sequence of bytes and append those bytes to bytes.

    3. Perform the underlying cryptographic algorithm, using bytes as the input data.

    4. If the cryptographic operation fails, execute the associated resolver's reject(value) algorithm, with value set to null, and terminate the algorithm.

    5. Let output be the result of the underlying cryptographic operation.

    Otherwise, if the underlying implementation supports multi-part cryptographic operations for the associated algorithm.
    Editorial note
    This section is a feature at risk, in light of ongoing discussions related to Streams, ProgressPromise, and idiomatic progressive outputting.
    1. If the internal count of available bytes does not contain enough data for the underlying cryptographic operation to yield output, terminate this algorithm.

    2. Let bytes be an empty sequence of bytes.

    3. Execute the following algorithm for each item in the list of pending data, ordered such that the oldest item is iterated first, until bytes contains sufficient data for the underlying cryptographic operation to yield output. Implementations MAY process additional data, provided the result of doing so is indistinguishable from the algorithm described here.

      1. Let item be the oldest remaining item in the list of pending data.

      2. Remove item from the list of pending data.

      3. Convert item to a sequence of bytes and append those bytes to bytes.

    4. Perform the underlying cryptographic algorithm, using bytes as the input data.

    5. If the cryptographic operation fails, execute the associated resolver's reject(value) algorithm, with value set to null, and terminate the algorithm.

    6. Let output be the result of the underlying cryptographic operation.

    7. Append output to the result field.

      Editorial note
      The intent of this section is to permit the use of ProgressPromise, allowing the CryptoOperation to progressively notify of progress being made.

12.2. Attributes

key

On getting, the key attribute returns the Key used to initialize the CryptoOperation.

If the CryptoOperation represents a keyless-operation, such as digesting, then key MUST return null.

algorithm
On getting, the algorithm attribute returns the normalized algorithm of the algorithm used to initialize the CryptoOperation.

12.3. Methods

12.3.1. process(ArrayBufferView data)

When the process(ArrayBufferView data) method is called, the user agent must run the following steps:

  1. If the associated resolver's resolved flag is set, terminate this algorithm.

  2. If the internal state of the CryptoOperation is not "processing", terminate this algorithm.

  3. Let data be the data to be processed.

  4. Add data to the list of pending data.

  5. Return the current CryptoOperation.

12.3.2. The finish() method

When finish() method is called, the user agent must run the steps below.

  1. If the associated resolver's resolved flag is set, terminate this algorithm.

  2. Set the internal state to "complete".

  3. If the list of pending data is empty, perform the following steps:
    1. Execute the associated resolver's resolve(value) algorithm, with output as value.

    2. Terminate the algorithm.

    Otherwise, return to the task that invoked this algorithm and continue the remaining steps asynchronously.
    1. Process data until the list of pending data is empty.

    2. Execute the associated resolver's resolve(value) algorithm, with output as value.

12.3.3. The abort() method

When abort() method is called, the user agent must run the steps below.

  1. If the associated resolver's resolved flag is set, terminate this algorithm.

  2. Set the internal state to "error"

  3. Clear the list of pending data.

  4. Execute the associate resolver's reject(value) algorithm, with value set to null.

13. Crypto interface

IDL

interface Crypto {
  readonly attribute SubtleCrypto subtle;
};

Crypto implements RandomSource;

partial interface Window {
  readonly attribute Crypto crypto;
};
        

14. SubtleCrypto interface

IDL

enum KeyFormat {
  // An unformatted sequence of bytes. Intended for secret keys.
  "raw",
  // The DER encoding of the PrivateKeyInfo structure from RFC 5208.
  "pkcs8",
  // The DER encoding of the SubjectPublicKeyInfo structure from RFC 5280.
  "spki",
  // The key is represented as JSON according to the JSON Web Key format.
  "jwk",
};

interface SubtleCrypto {
  CryptoOperation encrypt(AlgorithmIdentifier algorithm,
                          Key key,
                          optional ArrayBufferView? buffer = null);
  CryptoOperation decrypt(AlgorithmIdentifier algorithm,
                          Key key,
                          optional ArrayBufferView? buffer = null);
  CryptoOperation sign(AlgorithmIdentifier algorithm,
                       Key key,
                       optional ArrayBufferView? buffer = null);
  CryptoOperation verify(AlgorithmIdentifier algorithm,
                         Key key,
                         ArrayBufferView signature,
                         optional ArrayBufferView? buffer = null);
  CryptoOperation digest(AlgorithmIdentifier algorithm,
                         optional ArrayBufferView? buffer = null);

  // TBD: ISSUE-36
  Promise<any> generateKey(AlgorithmIdentifier algorithm,
                          bool extractable = false,
                          KeyUsage[] keyUsages = []);
  Promise<any> deriveKey(AlgorithmIdentifier algorithm,
                        Key baseKey,
                        AlgorithmIdentifier? derivedKeyType,
                        bool extractable = false,
                        KeyUsage[] keyUsages = []);
  
  // TBD: ISSUE-35
  Promise<any> importKey(KeyFormat format,
                        ArrayBufferView keyData,
                        AlgorithmIdentifier? algorithm,
                        bool extractable = false,
                        KeyUsage[] keyUsages = []);
  Promise<any> exportKey(KeyFormat format, Key key);

  // Note: wrap and unwrap remain "Features at Risk"
  Promise<any> wrapKey(KeyFormat format,
                      Key key,
                      Key wrappingKey,
                      AlgorithmIdentifier wrapAlgorithm);
  Promise<any> unwrapKey(KeyFormat format,
                        ArrayBufferView wrappedKey,
                        Key unwrappingKey,
                        AlgorithmIdentifier unwrapAlgorithm,
                        AlgorithmIdentifier? unwrappedKeyAlgorithm,
                        bool extractable = false,
                        KeyUsage[] keyUsages = []);
};
        
Editorial note
  • ISSUE-35: The specification for wrap/unwrap does not specify how authors that do not trust the execution environment may indicate required attributes for keys that are unwrapped. An example is unwrapping a key with a non-extractable key, marking the newly unwrapped key as non extractable, and then further indicating that all keys unwrapped with the newly unwrapped key are also non-extractable.
  • ISSUE-36: Further distinction is needed to clarify the differences between key generation and key derivation. Should they be distinguished by their inputs (Key generation takes parameters, while key derivation takes parameters + key(s)), by their outputs (Key generation generates Keys, key derivation generates opaque bytes as secret material), or is there some other construct to distinguish the two?

14.1. Description

This section is non-normative.

The SubtleCrypto interface provides a set of methods for dealing with low-level cryptographic primitives and algorithms. It is named SubtleCrypto to reflect the fact that many of these algorithms have subtle usage requirements in order to provide the required algorithmic security guarantees.

For example, the direct use of an unauthenticated encryption scheme, such as AES in counter mode, gives potential attackers the ability to manipulate bits in the output by manipulating bits in the input, compromising the integrity of the message. However, AES-CTR can be used securely in combination with other cryptographic primitives, such as message authentication codes, to ensure the integrity of the protected message, but only when the message authentication code is constructed over the encrypted message and IV.

Developers making use of the SubtleCrypto interface are expected to be aware of the security concerns associated with both the design and implementation of the various algorithms provided. The raw algorithms are provided in order to allow developers maximum flexibility in implementing a variety of protocols and applications, each of which may represent the composition and security parameters in a unique manner that necessitate the use of the raw algorithms.

14.2. Methods and Parameters

14.2.1. The encrypt method

The encrypt method returns a new CryptoOperation object that will encrypt data using the specified AlgorithmIdentifier with the supplied Key. It must act as follows:

  1. Let normalizedAlgorithm be the result of processing algorithm according to the algorithm normalizing rules.

  2. If normalizedAlgorithm does not describe a registered algorithm that supports the encrypt operation, throw a NotSupportedError and terminate the algorithm.

  3. Create a new CryptoOperation object S with the following characteristics:

    1. S.algorithm = normalizedAlgorithm.

    2. S.key = key.

    3. S.result = null.

  4. Return the new object and asynchronously perform the remaining steps.

  5. If buffer is specified:

    1. Execute the process(buffer) algorithm, with buffer as the buffer.

    2. Execute the finish() algorithm.

    Editorial note

    Supporting single-part operations is intended to address two use cases:

    1. Developers that "just" want to perform a simple operation. The single-method invocation best matches existing JavaScript cryptographic libraries, particularly the synchronous aspect.

    2. User agents that can optimize implementation when there is only a single operation being performed.

14.2.2. The decrypt method

The decrypt method returns a new CryptoOperation object that will decrypt data using the specified AlgorithmIdentifier with the supplied Key. It must act as follows:

  1. Let normalizedAlgorithm be the result of processing algorithm according to the algorithm normalizing rules.

  2. If normalizedAlgorithm does not describe a registered algorithm that supports the decrypt operation, throw a NotSupportedError and terminate the algorithm.

  3. Create a new CryptoOperation object S with the following characteristics:

    1. S.algorithm = normalizedAlgorithm.

    2. S.key = key.

    3. S.result = null.

  4. Return the new object and asynchronously perform the remaining steps.

  5. If buffer is specified:

    1. Execute the process(buffer) algorithm, with buffer as the buffer.

    2. Execute the finish() algorithm.

    Editorial note

    Supporting single-part operations is intended to address two use cases:

    1. Developers that "just" want to perform a simple operation. The single-method invocation best matches existing JavaScript cryptographic libraries, particularly the synchronous aspect.

    2. User agents that can optimize implementation when there is only a single operation being performed.

14.2.3. The sign method

The sign method returns a new CryptoOperation object that will sign data using the specified AlgorithmIdentifier with the supplied Key. It must act as follows:

  1. Let normalizedAlgorithm be the result of processing algorithm according to the algorithm normalizing rules.

  2. If normalizedAlgorithm does not describe a registered algorithm that supports the sign operation, throw a NotSupportedError and terminate the algorithm.

  3. Create a new CryptoOperation object S with the following characteristics:

    1. S.algorithm = normalizedAlgorithm.

    2. S.key = key.

    3. S.result = null.

  4. Return the new object and asynchronously perform the remaining steps.

  5. If buffer is specified:

    1. Execute the process(buffer) algorithm, with buffer as the buffer.

    2. Execute the finish() algorithm.

    Editorial note

    Supporting single-part operations is intended to address two use cases:

    1. Developers that "just" want to perform a simple operation. The single-method invocation best matches existing JavaScript cryptographic libraries, particularly the synchronous aspect.

    2. User agents that can optimize implementation when there is only a single operation being performed.

14.2.4. The verify method

The verify method returns a new CryptoOperation object that will verify data using the specified AlgorithmIdentifier with the supplied Key. It must act as follows:

  1. Let normalizedAlgorithm be the result of processing algorithm according to the algorithm normalizing rules.

  2. If normalizedAlgorithm does not describe a registered algorithm that supports the verify operation, throw a NotSupportedError and terminate the algorithm.

  3. Create a new CryptoOperation object S with the following characteristics:

    1. S.algorithm = normalizedAlgorithm.

    2. S.key = key.

    3. S.result = null.

  4. Return the new object and asynchronously perform the remaining steps.

  5. If buffer is specified:

    1. Execute the process(buffer) algorithm, with buffer as the buffer.

    2. Execute the finish() algorithm.

    Editorial note

    Supporting single-part operations is intended to address two use cases:

    1. Developers that "just" want to perform a simple operation. The single-method invocation best matches existing JavaScript cryptographic libraries, particularly the synchronous aspect.

    2. User agents that can optimize implementation when there is only a single operation being performed.

14.2.5. The digest method

The digest method returns a new CryptoOperation object that will digest data using the specified AlgorithmIdentifier. It must act as follows:

  1. Let normalizedAlgorithm be the result of processing algorithm according to the algorithm normalizing rules.

  2. If normalizedAlgorithm does not describe a registered algorithm that supports the digest operation, throw a NotSupportedError and terminate the algorithm.

  3. Create a new CryptoOperation object S with the following characteristics:

    1. S.algorithm = normalizedAlgorithm.

    2. S.key = null.

    3. S.result = null.

  4. Return the new object and asynchronously perform the remaining steps.

  5. If buffer is specified:

    1. Execute the process(buffer) algorithm, with buffer as the buffer.

    2. Execute the finish() algorithm.

    Editorial note

    Supporting single-part operations is intended to address two use cases:

    1. Developers that "just" want to perform a simple operation. The single-method invocation best matches existing JavaScript cryptographic libraries, particularly the synchronous aspect.

    2. User agents that can optimize implementation when there is only a single operation being performed.

14.2.6. The generateKey method

When invoked, generateKey MUST perform the following steps:

  1. Let normalizedAlgorithm be the result of processing algorithm according to the algorithm normalizing rules.

  2. If normalizedAlgorithm does not describe a registered algorithm that supports the generate operation, throw a NotSupportedError and terminate the algorithm.

  3. Let promise be a new Promise object and resolver its associated resolver.

  4. Return promise and continue executing the remaining steps asynchronously.

  5. If an error occurs, run these substeps and then terminate the algorithm:

    Editorial note
    Determine whether to reject the algorithm with a DOMError or a null result.
    1. Let result be null.

    2. Execute resolver's reject(value) algorithm, with result as the value argument.

  6. Let result be the result of executing the key generation algorithm defined by the algorithm indicated in normalizedAlgorithm.

  7. Execute resolver's resolve(value) algorithm, with result as the value argument.

14.2.7. The deriveKey method

When invoked, deriveKey MUST perform the following steps:

  1. Let normalizedAlgorithm be the result of processing algorithm according to the algorithm normalizing rules.

  2. If normalizedAlgorithm does not describe a registered algorithm that supports the derive operation, throw a NotSupportedError and terminate the algorithm.

  3. Let promise be a new Promise object and resolver its associated resolver.

  4. Return promise and continue executing the remaining steps asynchronously.

  5. If an error occurs, run these substeps and then terminate the algorithm:

    Editorial note
    Determine whether to reject the algorithm with a DOMError or a null result.
    1. Let result be null.

    2. Execute resolver's reject(value) algorithm, with result as the value argument.

  6. If baseKey.keyUsage does not contain the "derive" KeyUsage, terminate this algorithm with an error.

  7. Let result be the result of executing the key derivation algorithm defined by the algorithm indicated in normalizedAlgorithm.

  8. Execute resolver's resolve(value) algorithm, with result as the value argument.

14.2.8. The importKey method

14.2.9. The exportKey method

14.2.10. The wrapKey method

When invoked, the wrapKey method MUST perform the following steps:

  1. Let normalizedAlgorithm be the result of processing wrapAlgorithm according to the algorithm normalizing rules.

  2. If normalizedAlgorithm does not describe a registered algorithm that supports the derive operation, throw a NotSupportedError and terminate the algorithm.

  3. Let promise be a new Promise object and resolver its associated resolver.

  4. Return promise and continue executing the remaining steps asynchronously.

  5. If an error occurs, run these substeps and then terminate the algorithm:

    Editorial note
    Determine whether to reject the algorithm with a DOMError or a null result.
    1. Let result be null.

    2. Execute resolver's reject(value) algorithm, with result as the value argument.

  6. If wrappingKey.keyUsage does not contain the "wrap" KeyUsage, terminate this algorithm with an error.

  7. If Key.extractable is not true, terminate this algorithm with an error.

  8. Let bytes be the result of executing the exportKey algorithm, with the keyFormat as keyFormat and with key as key.

  9. If the key export algorithm failed, terminate this algorithm with an error.

  10. Let result be the result of executing the encrypt algorithm, with wrappingKey as Key, normalizedAlgorithm as algorithm, and with bytes as buffer.

  11. If the encrypt algorithm failed, terminate this algorithm with an error.

  12. Execute resolver's resolve(value) algorithm, with result as the value argument.

14.2.11. The unwrapKey method

When invoked, the unwrapKey method MUST perform the following steps:

  1. Let normalizedUnwrapAlgorithm be the result of processing unwrapAlgorithm according to the algorithm normalizing rules.

  2. If normalizedUnwrapAlgorithm does not describe a registered algorithm that supports the wrapKey operation, throw a NotSupportedError and terminate the algorithm.

    • If unwrappedKeyAlgorithm is defined:

      1. Let normalizedKeyAlgorithm be the result of processing unwrappedKeyAlgorithm according to the algorithm normalizing rules.

      2. If normalizedKeyAlgorithm does not describe a registered algorithm that supports the wrapKey operation, throw a NotSupportedError and terminate the algorithm.

    • Otherwise, let normalizedKeyAlgorithm be null.

  3. Let promise be a new Promise object and resolver its associated resolver.

  4. Return promise and continue executing the remaining steps asynchronously.

  5. If an error occurs, run these substeps and then terminate the algorithm:

    Editorial note
    Determine whether to reject the algorithm with a DOMError or a null result.
    1. Let result be null.

    2. Execute resolver's reject(value) algorithm, with result as the value argument.

  6. If unwrappingKey.keyUsage does not contain the "unwrap" KeyUsage, terminate this algorithm with an error.

  7. If Key.extractable is not true, terminate this algorithm with an error.

  8. Let bytes be the result of executing the decrypt algorithm, with unwrapAlgorithm as algorithm, unwrapKey as key, and with wrappedKey as buffer.

  9. If the key decrypt algorithm failed, terminate this algorithm with an error.

  10. Let result be the result of executing the importKey algorithm, with format as format, with bytes as keyData, with unwrappedKeyAlgorithm as algorithm, with extractable as extractable, and keyUsages as keyUsages.

  11. If the key import algorithm failed, terminate this algorithm with an error.

  12. Execute resolver's resolve(value) algorithm, with result as the value argument.

15. WorkerCrypto interface

IDL

interface WorkerCrypto {
};

WorkerCrypto implements RandomSource;

partial interface WorkerGlobalScope {
  readonly attribute WorkerCrypto crypto;
};
        

15.1. Description

The WorkerCrypto interface provides cryptographic functionality for background scripts, as specified by Web Workers [ Web Workers].

Editorial note

A unique interface exposing only a subset of the Crypto is provided as it has not yet been determined how Keys should be shared amongst threads, nor how user interaction should be managed for operations that may require user consent.

16. BigInteger

IDL

typedef Uint8Array BigInteger;
        

The BigInteger typedef is a Uint8Array that holds a multiple-precision unsigned integer. Each Uint8 element in the array represents a base-256 digit of the integer. The digits are in big-endian order: the first Uint8 element in the array is the most significant digit. A leading zero Uint8 element is not needed if the most significant bit of the integer is set.

17. KeyPair

IDL

interface KeyPair {
  Key publicKey;
  Key privateKey;
};
        

The KeyPair interface represents an asymmetric key pair that is comprised of both public and private keys.

18. Algorithms

Editorial note

Note: All algorithms listed should be considered as "features at risk", barring implementors adopting them. Their inclusion in the Editor's Draft reflects requests for their inclusion by members of the community, and are included as an exercise to ensure the robustness of the API defined in this specification.

As such, the list of algorithms, and the recommendations, may be significantly altered in future revisions.

18.2. Defining an algorithm

Each algorithm that is to be exposed via the Web Cryptography API SHOULD be registered via the Web Cryptography working group, and MUST include all of the following details. Algorithms that are not registered via these means, but are exposed via this API, MUST be processed as if the sections had been defined.

18.2.1. Recognized algorithm name

Each registered algorithm MUST have a canonical name for which applications can refer to the algorithm. The canonical name MUST contain only ASCII characters and MUST NOT equal any other canonical name or algorithm alias when every character in both names are converted to lower case.

18.2.2. Supported operations

Each registered algorithm MUST define the operations that it supports.

18.2.3. Algorithm-specific parameters

Each registered algorithm MUST define the expected parameters, if any, that should be exposed via the Algorithm dictionary for every supported operation.

18.2.4. Algorithm results

Each registered algorithm MUST define the contents of the result attribute of the CryptoOperation object for every supported operation.

18.2.5. Algorithm aliases

Each registered algorithm MAY define one or more aliases that may define a fully normalized Algorithm object.

Each algorithm alias MUST follow the same naming rules as the recognized algorithm name.

18.3. RSAES-PKCS1-v1_5

18.3.1. Description

The "RSAES-PKCS1-v1_5" algorithm identifier is used to perform encryption and decryption ordering to the RSAES-PKCS1-v1_5 algorithm specified in [RFC3447].

18.3.2. Registration

The recognized algorithm name for this algorithm is "RSAES-PKCS1-v1_5".

Operation Parameters Result
encrypt None ArrayBuffer?
decrypt None ArrayBuffer?
generateKey RsaKeyGenParams KeyPair?

18.3.3. RsaKeyGenParams dictionary

IDL

dictionary RsaKeyGenParams : Algorithm {
  // The length, in bits, of the RSA modulus
  unsigned long modulusLength;
  // The RSA public exponent
  BigInteger publicExponent;
};
            

18.3.4. Operations

Editorial note

Note: The following processing algorithms have not been updated to match the processing algorithm described in the CryptoOperation processing model.

Encrypt
When encrypting, the resultant CryptoOperation shall behave as follows:
  1. When initializing the CryptoOperation:
    1. If key does not describe an RSA public key, raise an error and terminate the algorithm.
    2. Let M be an empty sequence of bytes.
  2. Upon invoking process:
    1. Let buffer be the ArrayBufferView to be processed.
    2. Convert buffer to a sequence of byteLength bytes from the underlying ArrayBuffer, starting at the byteOffset of the ArrayBufferView, and append those bytes to M.
    3. No output is returned.
  3. Upon invoking finish:
    1. Perform the RSAES-PKCS1-V1_5-ENCRYPT operation, as specified in RFC3447, Section 7.2.1, with M as the message, and with n and e obtained from the Key.
    2. If the operation resulted in an error, raise an error and terminate the algorithm.
    3. Let C be an array of bytes resulting from performing the RSAES-PKCS1-V1_5-ENCRYPT operation.
    4. Let output be an ArrayBuffer with enough bytes to hold C.length bytes, with the contents of the underlying buffer initialized to the contents of C.
Decrypt
When decrypting, the resultant CryptoOperation shall behave as follows:
  1. When initializing the CryptoOperation:
    1. If key does not describe an RSA private key, raise an error and terminate the algorithm.
    2. Let C be an empty sequence of bytes.
  2. Upon invoking process:
    1. Let buffer be the ArrayBufferView to be processed.
    2. Convert buffer to a sequence of byteLength bytes from the underlying ArrayBuffer, starting at the byteOffset of the ArrayBufferView, and append those bytes to C.
    3. No output is returned.
  3. Upon invoking finish:
    1. Perform the RSAES-PKCS1-V1_5-DECRYPT operation, as specified in RFC3447, Section 7.2.2, with C as the ciphertext, and with K obtained from the Key.
    2. If the operation resulted in an error, raise an error and terminate the algorithm.
    3. Let M be an array of bytes resulting from performing the RSAES-PKCS1-V1_5-DECRYPT operation.
    4. Let output be an ArrayBuffer with enough bytes to hold M.length bytes, with the contents of the underlying buffer initialized to the contents of M.
Generate Key

18.4. RSASSA-PKCS1-v1_5

18.4.1. Description

The "RSASSA-PKCS1-v1_5" algorithm identifier is used to perform signing and verification using the RSASSA-PKCS1-v1_5 algorithm specified in [RFC3447].

18.4.2. Registration

The recognized algorithm name for this algorithm is "RSASSA-PKCS1-v1_5".

Operation Parameters Result
sign RsaSsaParams ArrayBuffer?
verify RsaSsaParams boolean?
generateKey RsaKeyGenParams KeyPair?

18.4.3. RsaSsaParams dictionary

IDL

dictionary RsaSsaParams : Algorithm {
  // The hash algorithm to use 
  AlgorithmIdentifier hash;
};
            

18.4.4. Operations

  • Sign
  • Verify
  • Generate Key

18.5. RSA-PSS

18.5.1. Description

The "RSA-PSS" algorithm identifier is used to perform signing and verification using the RSASSA-PSS algorithm specified in [RFC3447], using the mask generation formula MGF-1.

18.5.2. Registration

The recognized algorithm name for this algorithm is "RSA-PSS".

Operation Parameters Result
sign RsaPssParams ArrayBuffer?
verify RsaPssParams boolean?
generateKey RsaKeyGenParams KeyPair?

18.5.3. RsaPssParams dictionary

IDL

dictionary RsaPssParams : Algorithm {
  // The hash function to apply to the message
  AlgorithmIdentifier hash;
  // The desired length of the random salt
  unsigned long saltLength;
};
            

18.5.4. Operations

  • Sign
  • Verify
  • Generate Key

18.6. RSA-OAEP

18.6.1. Description

The "RSA-OAEP" algorithm identifier is used to perform encryption and decryption ordering to the RSAES-OAEP algorithm specified in [RFC3447], using the mask generation function MGF-1.

18.6.2. Registration

The recognized algorithm name for this algorithm is "RSA-OAEP".

Operation Parameters Result
encrypt RsaOaepParams ArrayBuffer?
decrypt RsaOaepParams ArrayBuffer?
generateKey RsaKeyGenParams KeyPair?
wrap RsaOaepParams ArrayBuffer?
unwrap RsaOaepParams Key?

18.6.3. RsaOaepParams dictionary

IDL

dictionary RsaOaepParams : Algorithm {
  // The hash function to apply to the message
  AlgorithmIdentifier hash;
  // The optional label/application data to associate with the message
  ArrayBufferView? label;
};
            

18.6.4. Operations

Encrypt
Decrypt
Generate Key
Wrap
Unwrap

18.7. ECDSA

18.7.1. Description

The "ECDSA" algorithm identifier is used to perform signing and verification using the ECDSA algorithm specified in [X9.62].

18.7.2. Registration

The recognized algorithm name for this algorithm is "ECDSA".

Operation Parameters Result
sign EcdsaParams ArrayBuffer?
verify EcdsaParams boolean?
generateKey EcKeyGenParams KeyPair?

18.7.3. EcdsaParams dictionary

IDL

dictionary EcdsaParams : Algorithm {
  // The hash algorithm to use
  AlgorithmIdentifier hash;
};
            

18.7.4. EcKeyGenParams dictionary

IDL

enum NamedCurve {
  // NIST recommended curve P-256, also known as secp256r1.
  "P-256",
  // NIST recommended curve P-384, also known as secp384r1.
  "P-384",
  // NIST recommended curve P-521, also known as secp521r1.
  "P-521"
};

dictionary EcKeyGenParams : Algorithm {
  // A named curve
  NamedCurve namedCurve;
};
            

The NamedCurve enumeration type represents named elliptic curves, which are a convenient way to specify the domain parameters of well-known elliptic curves.

18.7.5. Operations

Sign
When signing, the resultant CryptoOperation shall behave as follows:
  1. If the context object's associated Key does not refer to an ECDSA private key, terminate the algorithm with an error.

  2. Upon the first attempt to process data, let hash be an initialized to an instance of the underlying hash algorithm indicated by the "hash" identifier of the context object's associated algorithm.

  3. Let bytes be the sequence of bytes to be processed.

  4. Perform the hash algorithm of hash, using bytes as input.

  5. If the context object's internal state is not "complete", return an empty ArrayBuffer.

  6. Let M be the result of finalizing the hash algorithm of hash.

  7. Let d be the ECDSA private key associated with the context object's associated Key.

  8. Let params be the EC domain parameters associated with the context object's associated Key.

  9. Perform the ECDSA signing process, as specified in X9.62, Section 7.3, with M as the message, using params as the EC domain parameters, and with d as the private key.

  10. Let r and s be the pair of integers resulting from performing the ECDSA signing process.

  11. Let result be a new ArrayBuffer.

  12. Convert r to a bitstring and append the sequence of bytes to result.

  13. Convert s to a bitstring and append the sequence of bytes to result.

  14. Return result.

Verify
When verifying, the resultant CryptoOperation shall behave as follows:
  1. If the context object's associated Key does not refer to an ECDSA public key, terminate the algorithm with an error.

  2. Upon the first attempt to process data, let hash be an initialized to an instance of the underlying hash algorithm indicated by the "hash" identifier of the context object's associated algorithm.

  3. Let bytes be the sequence of bytes to be processed.

  4. Perform the hash algorithm of hash, using bytes as input.

  5. If the context object's internal state is not "complete", terminate the algorithm.

  6. Let M be the result of finalizing the hash algorithm of hash.

  7. Let Q be the ECDSA public key associated with the context object's associated Key.

  8. Let params be the EC domain parameters associated with the context object's associated Key.

  9. Perform the ECDSA verifying process, as specified in X9.62, Section 7.4, with M as the received message, using params as the EC domain parameters, and with Q as the public key.

  10. Let result be a boolean indicating whether or not the purported signature is valid, with true indicating the signature is valid and false indicating it is invalid.

  11. Return result.

Generate Key

18.8. ECDH

18.8.1. Description

This describes using Elliptic Curve Diffie-Hellman (ECDH) for key generation and key agreement, as specified by X9.63.

18.8.2. Registration

The recognized algorithm name for this algorithm is "ECDH".

Operation Parameters Result
generateKey EcKeyGenParams KeyPair?
deriveKey EcdhKeyDeriveParams Key?

18.8.3. EcdhKeyDeriveParams dictionary

IDL

typedef Uint8Array ECPoint;

dictionary EcdhKeyDeriveParams : Algorithm {
  // The peer's EC public key.
  ECPoint public;
};
            

The ECPoint typedef is a Uint8Array holding an elliptic curve point. An elliptic curve point is converted to an array of Uint8 elements using the procedure specified in X9.62 Annex A.5.7.

18.8.4. Operations

  • Generate Key
  • Derive Key

    Perform the standard ECDH primitive specified in X9.63 Section 5.4.1. The output of ECDH key agreement is the x-coordinate of the shared secret value P.

    Note: X9.63 Section 5.4.2 and NIST SP 800-56A Section 5.7.1.2 specify a modified ECDH primitive that multiplies the shared secret value by the cofactor of the curve. The cofactor of the NIST recommended curves P-256, P-384, and P-521 is 1, so the standard and modified ECDH primitives are equivalent for those curves.

18.9. AES-CTR

18.9.1. Description

18.9.2. Registration

The recognized algorithm name for this algorithm is "AES-CTR".

Operation Parameters Result
encrypt AesCtrParams ArrayBuffer?
decrypt AesCtrParams ArrayBuffer?
generateKey AesKeyGenParams Key?

18.9.3. AesCtrParams dictionary

IDL

dictionary AesCtrParams : Algorithm {
  // The initial value of the counter block. counter MUST be 16 bytes
  // (the AES block size). The counter bits are the rightmost length
  // bits of the counter block. The rest of the counter block is for
  // the nonce. The counter bits are incremented using the standard
  // incrementing function specified in NIST SP 800-38A Appendix B.1:
  // the counter bits are interpreted as a big-endian integer and
  // incremented by one.
  ArrayBuffer counter;
  // The length, in bits, of the rightmost part of the counter block
  // that is incremented.
  [EnforceRange] octet length;
};
            

18.9.4. AesKeyGenParams dictionary

IDL

dictionary AesKeyGenParams : Algorithm {
  // The length, in bits, of the key.
  [EnforceRange] unsigned short length;
};
            

18.9.5. Operations

  • Encrypt
  • Decrypt
  • Generate Key

18.10. AES-CBC

18.10.1. Description

This section is non-normative.

The "AES-CBC" algorithm identifier is used to perform encryption and decryption using AES in Cipher Block Chaining mode, as described in NIST SP 800-38A [SP800-38A].

When operating in CBC mode, messages that are not exact multiples of the AES block size (16 bytes) can be padded under a variety of padding schemes. In the Web Crypto API, the only padding mode that is supported is that of PKCS#5 and PKCS#7, as described by Section 6.1.1, p4 of RFC 2898 [RFC2898] and Section 10.3, p2 of RFC 2315 [RFC2315].

18.10.2. Registration

The recognized algorithm name for this algorithm is "AES-CBC".

Operation Parameters Result
encrypt AesCbcParams ArrayBuffer?
decrypt AesCbcParams ArrayBuffer?
generateKey AesKeyGenParams Key?

18.10.3. AesCbcParams dictionary

IDL

dictionary AesCbcParams : Algorithm {
  // The initialization vector. MUST be 16 bytes.
  ArrayBufferView iv;
};
            

18.10.4. Operations

  • Encrypt
  • Decrypt
  • Generate Key

18.11. AES-CMAC

18.11.1. Description

This section is non-normative.

The "AES-CMAC" algorithm identifier is used to perform message authentication using AES with a cipher-based MAC, as described in NIST SP 800-38B [SP800-38B].

18.11.2. Registration

The recognized algorithm name for this algorithm is "AES-CMAC".

Operation Parameters Result
sign None ArrayBuffer?
verify None boolean?
generateKey AesKeyGenParams Key?

18.11.3. Operations

  • Sign
  • Verify
  • Generate Key

18.12. AES-GCM

18.12.1. Description

18.12.2. Registration

The recognized algorithm name for this algorithm is "AES-GCM".

Operation Parameters Result
encrypt AesGcmParams ArrayBuffer?
decrypt AesGcmParams ArrayBuffer?
generateKey AesKeyGenParams Key?

18.12.3. AesGcmParams dictionary

IDL

dictionary AesGcmParams : Algorithm {
  // The initialization vector to use. May be up to 2^56 bytes long.
  ArrayBufferView? iv;
  // The additional authentication data to include.
  ArrayBufferView? additionalData;
  // The desired length of the authentication tag. May be 0 - 128.
  [EnforceRange] octet? tagLength;
};
            

18.12.4. Operations

  • Encrypt
  • Decrypt
  • Generate Key

18.13. AES-CFB

18.13.1. Description

This section is non-normative.

The "AES-CFB" algorithm identifier is used to perform encryption and decryption using AES in Cipher Feedback mode, as described in Section 6.3 of NIST SP 800-38A [SP800-38A].

18.13.2. Registration

The recognized algorithm name for this algorithm is "AES-CFB".

Operation Parameters Result
encrypt AesCfbParams ArrayBuffer?
decrypt AesCfbParams ArrayBuffer?
generateKey AesKeyGenParams Key?

18.13.3. AesCfbParams dictionary

IDL

dictionary AesCfbParams : Algorithm {
  // The initialization vector. MUST be 16 bytes.
  ArrayBufferView iv;
};
            

18.13.4. Operations

  • Encrypt
  • Decrypt
  • Generate Key

18.14. HMAC

18.14.1. Description

18.14.2. Registration

The recognized algorithm name for this algorithm is "HMAC".

Operation Parameters Result
sign HmacParams ArrayBuffer?
verify HmacParams boolean?
generateKey HmacParams Key?

18.14.3. HmacParams dictionary

IDL

dictionary HmacParams : Algorithm {
  // The inner hash function to use.
  AlgorithmIdentifier hash;
};
            

18.14.4. Operations

  • Sign
  • Verify
  • Generate Key

18.15. Diffie-Hellman

18.15.1. Description

This describes using Diffie-Hellman for key generation and key agreement, as specified by PKCS #3.

18.15.2. Registration

The recognized algorithm name for this algorithm is "DH".

Operation Parameters Result
generateKey DhKeyGenParams KeyPair?
deriveKey DhKeyDeriveParams Key?

18.15.3. DhKeyGenParams dictionary

IDL

dictionary DhKeyGenParams : Algorithm {
  // The prime p.
  BigInteger prime;
  // The base g.
  BigInteger generator;
};
            

18.15.4. DhKeyDeriveParams dictionary

IDL

dictionary DhKeyDeriveParams : Algorithm {
  // The peer's public value.
  BigInteger public;
};
            

18.15.5. Operations

  • Generate Key
  • Derive Key

18.16. SHA

18.16.1. Description

This describes the SHA-1 and SHA-2 families, as specified by [FIPS 180-4].

18.16.2. Registration

The following algorithms are added as recognized algorithm names:

"SHA-1"
The SHA-1 algorithm as specified in Section 6.1
"SHA-224"
The SHA-224 algorithm as specified in Section 6.3
"SHA-256"
The SHA-256 algorithm as specified in Section 6.2
"SHA-384"
The SHA-384 algorithm as specified in Section 6.5
"SHA-512"
The SHA-512 algorithm as specified in Section 6.4
Operation Parameters Result
digest None ArrayBuffer?

18.16.3. Operations

  • Digest

18.17. Concat KDF

18.17.1. Description

The "CONCAT" algorithm identifier is used to perform key derivation using the key derivation algorithm defined in Section 5.8.1 of NIST SP 800-56A [SP800-56A].

18.17.2. Registration

The recognized algorithm name for this algorithm is "CONCAT".

Operation Parameters Result
deriveKey ConcatParams Key?

18.17.3. ConcatParams dictionary

IDL

dictionary ConcatParams : Algorithm {
  // The digest method to use to derive the keying material.
  AlgorithmIdentifier hash;

  // A bit string corresponding to the AlgorithmId field of the OtherInfo parameter.
  // The AlgorithmId indicates how the derived keying material will be parsed and for which
  // algorithm(s) the derived secret keying material will be used.
  ArrayBufferView algorithmId;

  // A bit string that corresponds to the PartyUInfo field of the OtherInfo parameter.
  ArrayBufferView partyUInfo;
  // A bit string that corresponds to the PartyVInfo field of the OtherInfo parameter.
  ArrayBufferView partyVInfo;
  // An optional bit string that corresponds to the SuppPubInfo field of the OtherInfo parameter.
  ArrayBufferView? publicInfo;
  // An optional bit string that corresponds to the SuppPrivInfo field of the OtherInfo parameter.
  ArrayBufferView? privateInfo;
};
            

18.17.4. Operations

  • Derive Key

18.18. HKDF-CTR

18.18.1. Description

This section is non-normative.

The "HKDF-CTR" algorithm identifier is used to perform key derivation using the algorithm described in RFC 5869 [RFC5869] and NIST SP 800-56C [SP800-56C], using HMAC in counter mode, as described in Section 5.1 of NIST SP 800-108 [SP800-108].

18.18.2. Registration

The recognized algorithm name for this algorithm is "HKDF-CTR".

Operation Parameters Result
deriveKey HkdfCtrParams Key?

18.18.3. HkdfCtrParams dictionary

IDL

dictionary HkdfCtrParams : Algorithm {
  // The algorithm to use with HMAC (eg: SHA-256
  AlgorithmIdentifier hashAlg;
  // A bit string that corresponds to the label that identifies the purpose for the derived keying material.
  ArrayBufferView label;
  // A bit string that corresponds to the context of the key derivation, as described in Section 5 of NIST SP 800-108 [SP800-108]
  ArrayBufferView context;
};
            
Editorial note

The definition of HKDF allows the caller to supply an optional pseudorandom salt value, which is used as the key during the extract phase. If this value is not supplied, an all zero string is used instead. However, support for an explicit salt value is not widely implemented in existing APIs, nor is it required by existing usages of HKDF. Should this be an optional parameter, and if so, what should the behaviour be of a user agent that does not support explicit salt values (is it conforming or non-conforming?)

18.18.4. Operations

  • Derive Key

18.19. PBKDF2

18.19.1. Description

18.19.2. Registration

The recognized algorithm name for this algorithm is "PBKDF2".

Operation Parameters Result
deriveKey Pbkdf2Params Key?

18.19.3. Pbkdf2Params dictionary

IDL

dictionary Pbkdf2Params : Algorithm {
  ArrayBufferView salt;
  [Clamp] unsigned long iterations;
  AlgorithmIdentifier prf;
  ArrayBufferView? password;
};
            
Editorial note

In the above snippet, password is an optional field. The intent is that conforming user agents MAY support applications that wish to use PBKDF2 by providing password entry via an un-spoofable (by the web application) UI.

18.19.4. Operations

  • Derive Key

19. Algorithm normalizing rules

The AlgorithmIdentifier typedef permits algorithms to be specified as either a dictionary or a DOMString. In order to ensure consistency, conforming user agents must normalize all AlgorithmIdentifier inputs into a single, canonical form. When normalization is indicated, it must act as follows:

  1. Let O be the AlgorithmIdentifier to be normalized.
  2. Let result be the normalized output.
  3. If O is a DOMString, then:
    1. If O contains any non-ASCII characters, throw a SyntaxError and return from this algorithm.
    2. Convert every character in O to lower case.
    3. If O contains a recognized algorithm alias then let result be re-initialized to the aliased dictionary and this algorithm restarted, using result as the input to be normalized.
    4. Otherwise, throw an InvalidAlgorithmError exception and return from this algorithm.
  4. For each key K in O with an associated value V:
    • If the associated value V is an AlgorithmIdentifier, set the associated value for K in result to be the result of executing the algorithm normalization rules.
    • If the associated value V is a dictionary, set the associated value for K in result to be the result of executing this algorithm recursively for every value in the dictionary.
    • Otherwise, let the associated value for key K in result be the associated value for key K in O.
  5. Return result.

20. JavaScript Example Code

20.1. Generate a signing key pair, sign some data

ECMAScript

// Algorithm Object
var algorithmKeyGen = {
  name: "RSASSA-PKCS1-v1_5",
  // RsaKeyGenParams
  modulusLength: 2048,
  publicExponent: new Uint8Array([0x01, 0x00, 0x01]),  // Equivalent to 65537
};

var algorithmSign = {
  name: "RSASSA-PKCS1-v1_5",
  // RsaSsaParams
  hash: {
    name: "SHA-256",
  }
};

window.crypto.subtle.generateKey(algorithmKeyGen, false, ["sign"]).then(
  function(key) {
    var dataPart1 = convertPlainTextToArrayBufferView("hello,");
    var dataPart2 = convertPlainTextToArrayBufferView(" world!");
    // TODO: create example utility function that converts text -> ArrayBufferView

    // Because we are not supplying data to .sign(), a multi-part
    // CryptoOperation will be returned, which requires us to call .process()
    // and .finish().
    return window.crypto.subtle.sign(algorithmSign, key.privateKey)
      .process(dataPart1)
      .process(dataPart2)
      .finish();
  },
  console.error.bind(console, "Unable to generate a key")
).then(
  console.log.bind(console, "The signature is: "),
  console.error.bind(console, "Unable to sign")
);
        

20.2. Symmetric Encryption

ECMAScript

var clearDataArrayBufferView = convertPlainTextToArrayBufferView("Plain Text Data");
// TODO: create example utility function that converts text -> ArrayBufferView

var aesAlgorithmKeyGen = {
  name: "AES-CBC",
  // AesKeyGenParams
  length: 128
};

var aesAlgorithmEncrypt = {
  name: "AES-CBC",
  // AesCbcParams
  iv: window.crypto.getRandomValues(new Uint8Array(16))
};

// Create a keygenerator to produce a one-time-use AES key to encrypt some data
window.crypto.subtle.generateKey(aesAlgorithmKeyGen, false, ["encrypt"]).then(
  function(aesKey) {
    // Unlike the signing operation, which showed a multi-part operation,
    // here we perform the entire AES operation in a single call.
    return window.crypto.subtle.encrypt(aesAlgorithmEncrypt, aesKey, clearDataArrayBufferView);
  }
).then(console.log.bind(console, "The ciphertext is: "),
       console.error.bind(console, "Unable to encrypt"));
        

21. Acknowledgements

The editors would like to thank Adam Barth, Alex Russell, Ali Asad, Arun Ranganathan, Brian Smith, Brian Warner, Channy Yun, Jim Schaad, Kai Engert, Mark Watson, Nick Van den Bleeken, Richard Barnes, Vijay Bharadwaj, Virginie Galindo, and Wan-Teh Chang for their technical feedback and assistance.

Thanks to the W3C Web Cryptography WG, and to participants on the public-webcrypto@w3.org mailing list.

The W3C would like to thank the Northrop Grumman Cybersecurity Research Consortium for supporting W3C/MIT.

The getRandomValues method in the Crypto interface was originally proposed by Adam Barth to the WHATWG.

22. References

22.1. Normative References

DOM4
DOM (Living Standard), A. Gregor, A. van Kesteren, Ms2ger. WHATWG.
Editorial note
This will be updated to W3C DOM4 once Promises are incorporated.
ECMAScript
ECMAScript 5th Edition, A. Wirfs-Brock, P. Lakshman et al.
FIPS 180-4
FIPS PUB 180-4: Secure Hash Standard, NIST.
HTML
HTML5: A vocabulary and associated APIs for HTML and XHTML (work in progress), I. Hickson. W3C.
PKCS3
PKCS #3: Diffie-Hellman Key-Agreement Standard, RSA Laboratories.
RFC2119
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF.
RFC3447
Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1, J. Jonsson, B. Kaliski. IETF.
RFC5208
Public-Key Cryptography Standards (PKCS) #8: Private-Key Information Syntax Specification Version 1.2, B. Kaliski. IETF.
RFC5280
Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile, D. Cooper, S. Santesson, S. Farrell, S. Boeyen, R. Housley, W. Polk. IETF.
Typed Arrays
Typed Arrays (work in progress), V. Vukicevic, K. Russell. Khronos Group.
WebIDL Specification
WebIDL (work in progress), C. McCormack.
X9.62
ANS X9.62–2005: Public Key Cryptography for the Financial Services Industry, The Elliptic Curve Digital Signature Algorithm (ECDSA), ANSI.
X9.63
ANS X9.63–2001: Public Key Cryptography for the Financial Services Industry, Key Agreement and Key Transport Using Elliptic Curve Cryptography, ANSI.

22.2. Informative References

CDSA
Common Security: CDSA and CSSM, Version 2 (with corrigenda), the Open Group.
CNG
Cryptography API: Next Generation, Microsoft Corporation.
CryptoAPI
Cryptography Reference, Microsoft Corporation.
DRAFT-TLS-OBC
TLS Origin-Bound Certificates, D. Balfanz, D. Smetters, M. Upadhyay, A. Barth. IETF.
FileAPI
File API, A. Ranganathan, J. Sicking. W3C.
PKCS11
PKCS #11: Cryptographic Token Interface Standard, RSA Laboratories.
RFC 2315
PKCS #7: Cryptographic Message Syntax, Version 1.5, B. Kaliski. RSA Laboratories.
RFC 2898
PKCS #5: Password-Based Cryptography Specification, Version 2.0, B. Kaliski. RSA Laboratories
RFC 5705
Keying Material Exporters for Transport Layer Security (TLS), E. Rescorla. IETF.
RFC 5869
HMAC-based Extract-and-Expand Key Derivation Function (HKDF), H. Krawczyk, P. Eronen. IETF.
NIST SP 800-38A
NIST Special Publication 800-38A: Recommendation for Block Cipher Modes of Operation, Methods and Techniques, December 2001, NIST.
NIST SP 800-38B
NIST Special Publication 800-38B: Recommendation for Block Cipher Modes of Operation: The CMAC Mode for Authentication, May 2005, NIST.
NIST SP 800-56A
NIST Special Publication 800-56A: Recommendation for Pair-Wise Key Establishment Schemes Using Discrete Logarithm Cryptography (Revised), March 2007, NIST.
NIST SP 800-56C
NIST Special Publication 800-56C: Recommendation for Key Derivation through Extraction-then-Expansion, November 2011, NIST.
NIST SP 800-108
NIST Special Publication 800-108: Recommendation for Key Derivation Using Pseudorandom Functions (Revised), October 2009, NIST.
StreamsAPI
Streams API , F. Moussa. W3C.