W3C

Web Cryptography API

W3C Candidate Recommendation NaN @@ view

This Version:
https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html
Latest Published Version:
http://www.w3.org/TR/WebCryptoAPI/
Latest Editor’s Draft:
https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html
Previous Version(s):
https://dvcs.w3.org/hg/webcrypto-api/raw-file/0fe9b34c13fb/spec/Overview.html
Editors:
Ryan Sleevi, Google, Inc. <sleevi@google.com>
Mark Watson, Netflix <watsonm@netflix.com>
Participate:

Send feedback to public-webcrypto@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 NaN @@ view Candidate Recommendation 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 Candidate Recommendation 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 SubtleCrypto 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.

Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)

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.

Unless otherwise stated, string comparisons are done in a case-sensitive manner. String literals in this specification written in monospace font like "this" do not include the enclosing quotes.

3.1. Extensibility

Vendor-specific proprietary extensions to this specification are strongly discouraged. Authors must not use such extensions, as doing so reduces interoperability and fragments the user base, allowing only users of specific user agents to access the content in question.

If vendor-specific extensions are needed, the members should be prefixed by vendor-specific strings to prevent clashes with future versions of this specification. Extensions must be defined so that the use of extensions neither contradicts nor causes the non-conformance of functionality defined in the specification.

When vendor-neutral extensions to this specification are needed, either this specification can be updated accordingly, or an extension specification can be written that overrides the requirements in this specification. When someone applying this specification to their activities decides that they will recognize the requirements of such an extension specification, it becomes an applicable specification for the purposes of conformance requirements in this specification. Applicable specifications defined by the W3C WebCrypto Working Group are listed in the table below.

Specification Reference
Note
Readers are advised to consult the errata to this specification for updates to the table above.

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 CryptoKey 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. Concepts

This section is non-normative.

5.1. Underlying Cryptographic Implementation

This specification assumes, but does not require, that conforming user agents do not and will not be directly implementing cryptographic operations within the user agent itself. Historically, many user agents have deferred cryptographic operations, such as those used within TLS, to existing APIs that are available as part of the underlying operating system or to third-party modules that are managed independently of the user agent.

The CryptoKey object represents the bridge between the JavaScript execution environment and these underlying libraries, through the use of the internal slot named [[handle]]. The handle represents an opaque type that is implementation specific, which may not be represented within a JavaScript type, nor is it ever exposed to script authors. In this way, the CryptoKey object is the conceptual equivalent to the JavaScript executing environment as the [[handle]] is to the underlying cryptographic implementation.

These APIs are traditionally built around a notion of cryptographic providers, an abstraction for a specific implementation of a set of algorithms. The operating system or library may come with a default provider, and users are frequently allowed to add additional providers, reconfigure the set of enabled algorithms, or otherwise customize how cryptographic services are provided.

While it is assumed that most user agents will be interacting with a cryptographic provider that is implemented purely in software, it is not required by this specification. As a result, the capabilities of some implementations may be limited by the capabilities of the underlying hardware, and, depending on how the user has configured the underlying cryptographic library, this may be entirely opaque to the User Agent.

5.2. Key Storage

This specification does not explicitly provide any new storage mechanisms for CryptoKey objects. Instead, by allowing the CryptoKey to be used with the structured clone algorithm, any existing or future web storage mechanisms that support storing structured clonable objects can be used to store CryptoKey objects.

In practice, it is expected that most authors will make use of the Indexed Database API, which allows associative storage of key/value pairs, where the key is some string identifier meaningful to the application, and the value is a CryptoKey object. This allows the storage and retrieval of key material, without ever exposing that key material to the application or the JavaScript environment. Additionally, this allows authors the full flexibility to store any additional metadata with the CryptoKey itself.

6. Security considerations

This section is non-normative.

6.1. Security considerations for implementers

By not providing an explicit storage mechanism, this specification assumes that CryptoKey objects are scoped to the current execution environment and any storage mechanisms available to that environment (e.g. Indexed Database API). Application authors rely upon this for the security of their applications; two origins with the same CryptoKey object have full access to the underlying key, and as such, messages from these applications cannot be distinguished, and messages sent to these applications can be fully recovered. Implementors should ensure that no CryptoKey objects are shared between two origins unless the author has explicitly chosen to share (e.g., such as through the use of postMessage)

A number of algorithms specified within this specification perform computationally intensive work, such as the generation of significantly large prime numbers, or through repeated iterations of a particular operation. As such, hostile applications may attempt to misuse this API and attempt to cause significant amount of work to be performed by an implementation, denying access or services to other applications that are executing. Implementations should take steps to mitigate these risks, such as limiting the amount of operations an implementation performs concurrently, requiring user consent for operations that may be known to be disruptive for the executing environment, or defining device-specific limits on attributes such as key sizes or iteration counts.

6.2. Security considerations for authors

This specification includes descriptions for a variety of cryptographic operations, some of which have known weaknesses when used inappropriately. Application developers must take care and review appropriate and current cryptographic literature, to understand and mitigate such issues. In general, application developers are strongly discouraged from inventing new cryptographic protocols; as with all applications, users of this specification will be best served through the use of existing protocols, of which this specification provides the necessary building blocks to implement.

In order to use the APIs defined in this specification to provide any meaningful cryptographic assurances, authors must be familiar with existing threats to web applications, as well as the underlying security model employed. Conceptually, issues such as script injection are the equivalent to remote code execution in other operating environments, and allowing hostile script to be injected may allow for the exfiltration of keys or data. Script injection may come from other applications, for which the judicious use of Content Security Policy may mitigate, or it may come from hostile network intermediaries, for which the use of Transport Layer Security may mitigate.

This specification does not define any specific mechanisms for the storage of cryptographic keys. By default, unless specific effort is taken by the author to persist keys, such as through the use of the Indexed Database API, keys created with this API will only be valid for the duration of the current page (e.g. until a navigation event). Authors that wish to use the same key across different pages or multiple browsing sessions must employ existing web storage technologies. Authors should be aware of the security assumptions of these technologies, such as the same-origin security model; that is, any application that shares the same scheme, host, and port have access to the same storage partition, even if other information, such as the path, may differ. Authors may explicitly choose to relax this security through the use of inter-origin sharing, such as postMessage.

Authors should be aware that this specification places no normative requirements on implementations as to how the underlying cryptographic key material is stored. The only requirement is that key material is not exposed to script, except through the use of the exportKey and wrapKey operations. In particular, it does not guarantee that the underlying cryptographic key material will not be persisted to disk, possibly unencrypted, nor that it will be inaccessible to users or other applications running with the same privileges as the User Agent. Any application or user that has access to the device storage may be able to recover the key material, even through scripts may be prohibited.

This specification places no normative requirements on how implementations handle key material once all references to it go away. That is, conforming user agents are not required to zeroize key material, and it may still be accessible on device storage or device memory, even after all references to the CryptoKey have gone away.

Applications may share a CryptoKey object across security boundaries, such as origins, through the use of the structured clone algorithm and APIs such as postMessage. While access to the underlying cryptographic key material may be restricted, based upon the extractable attribute, once a key is shared with a destination origin, the source origin can not later restrict or revoke access to the key. As such, authors must be careful to ensure they trust the destination origin to take the same mitigations against hostile script that the source origin employs. Further, in the event of script injection on the source origin, attackers may post the key to an origin under attacker control. Any time that the user agent visits the attacker's origin, the user agent may be directed to perform cryptographic operations using that key, such as the decryption of existing messages or the creation of new, fraudulent messages.

Authors should be aware that users may, at any time, choose to clear the storage associated with an origin, potentially destroying keys. Applications that are meant to provide long-term storage, such as on the server, should consider techniques such as key escrow to prevent such data from being inaccessible. Authors should not presume that keys will be available indefinitely.

6.3. Security considerations for users

Users of applications that employ the APIs defined in this specification should be aware that these applications will have full access to all messages exchanged, regardless of the cryptography employed. That is, for messages that are encrypted, applications that use these APIs will have full access to the decrypted message as well.

7. Privacy considerations

This section is non-normative.

Fingerprinting
By exposing additional APIs that reflect capabilities of the underlying platform, this specification may allow malicious applications to determine or distinguish different user agents or devices.
Super-cookies
This specification does not provide any means for malicious applications to create identifiers that outlive existing web storage technologies. However, care must be taken when introducing future revisions to this API or additional cryptographic capabilities, such as those that are hardware backed (e.g.: smart cards or Trusted Platform Modules). Considering that such storage is designed to prevent any two users from having the same underlying key data, such APIs may represent a real risk of being used as a permanent identifier against the user's wishes.

8. 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 and DOMException. [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 the ArrayBufferView typedef and the structured clone algorithm. [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]

9. Terminology

The terms and algorithms ArrayBuffer, ArrayBufferView, and structured clone, are defined by the HTML specification [HTML].

The terms DOMString and BufferSource are defined in [WebIDL].

An octet string is an ordered sequence of zero or more integers, each in the range 0 to 255 inclusive.

Comparing two strings in a case-sensitive manner means comparing them exactly, code point for code point.

Comparing two strings in a ASCII case-insensitive manner means comparing them exactly, code point for code point, except that the codepoints in the range U+0041 .. U+005A (i.e. LATIN CAPITAL LETTER A to LATIN CAPITAL LETTER Z) and the corresponding codepoints in the range U+0061 .. U+007A (i.e. LATIN SMALL LETTER A to LATIN SMALL LETTER Z) are also considered to match.

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.

When this specification says to parse an ASN.1 structure, the user agent must perform the following steps:

  1. Let data be a sequence of bytes to be parsed.

  2. Let structure be the ASN.1 structure to be parsed.

  3. Let exactData be an optional boolean value. If it is not supplied, let it be initialized to true.

  4. Parse data according to the Distinguished Encoding Rules of X.690 (11/08), using structure as the ASN.1 structure to be decoded.

  5. If exactData was specified, and all of the bytes of data were not consumed during the parsing phase, then throw a DataError.

  6. Return the parsed ASN.1 structure.

When this specification says to parse a subjectPublicKeyInfo, the user agent must parse an ASN.1 structure, with data set to the sequence of bytes to be parsed, structure as the ASN.1 structure of subjectPublicKeyInfo, as specified in RFC 5280, and exactData set to true.

When this specification says to parse a PrivateKeyInfo, the user agent must parse an ASN.1 structure with data set to the sequence of bytes to be parsed, structure as the ASN.1 structure of PrivateKeyInfo, as specified in RFC 5208, and exactData set to true.

When this specification says to parse a JWK, the user agent must run the following steps:

  1. Let data be the sequence of bytes to be parsed.

  2. Let json be the Unicode string that results from interpreting data according to UTF-8.

  3. Convert json to UTF-16.

  4. Let result be the object literal that results from executing the JSON.parse internal function, with text argument set to a JavaScript String containing json.

  5. Let key be the result of converting result to the IDL dictionary type of JsonWebKey.

  6. If the "kty" field of key is not defined, then throw a DataError.

  7. Return key.

When this specification says to clone the data of a BufferSource object data, the user agent must run the following steps:

If data is an ArrayBuffer:
Return the result of invoking the ArrayBuffer.prototype.slice method on data, with the start value set to the integer 0, and the end value set to the value of the [[ArrayBufferByteLength]] internal slot of data.
If data is an ArrayBufferView:
  1. Let buffer be the value of the [[ViewedArrayBuffer]] internal slot of data.

  2. Let start be the value of the [[ByteOffset]] internal slot of data.

  3. Let end be the value of the [[ByteLength]] internal slot of data.

  4. Let relativeEnd be start+end.

  5. Return the result of invoking the ArrayBuffer.prototype.slice method on buffer, with the start value set to start and the end value set to relativeEnd.

Editorial note

The above definition makes heavy use of directly accessing the internal slot values, defined in ECMA262. The motivation for this is to avoid issues that might arise with authors defining custom getters/setters on such objects. However, it has the downside of avoiding the error control statements defined in the %TypedArray%.prototype getters and ArrayBuffer.prototype getters, which would be desirable.

It is assumed that the Web IDL conversion rules will perform the necessary type checks, and that as a result of these checks, it is guaranteed that the internal slots will always have valid values for the above algorithm. However, that assumption may not be safe to make.

When this specification states to supply the contents of an ArrayBuffer named data to an underlying cryptographic implementation, the User Agent shall supply a contiguous sequence of bytes that is equal to the contents of the Data Block value of the [[ArrayBufferData]] internal slot of data, and whose length in bytes is equal to the [[ArrayBufferByteLength]] internal slot of data.

When this specification says to calculate the usage intersection of two sequences, a and b the result shall be a sequence containing each recognized key usage value that appears in both a and b, in the order listed in the list of recognized key usage values, where a value is said to appear in a sequence if an element of the sequence exists that is a case-sensitive string match for that value.

When this specification says to calculate the normalized value of a usages list, usages the result shall be the usage intersection of usages and a sequence containing all recognized key usage values.

When this specification refers to the cached ECMAScript object associated with an internal slot [[slot]] of object, the user agent must run the following steps:

  1. If the [[slot_cached]] internal slot of object is undefined:
    Set the [[slot_cached]] internal slot of object to the result of performing type conversion to an ECMAScript object as defined in [WebIDL] to the contents of the [[slot]] internal slot of object.
  2. Return the contents of the [[slot_cached]] internal slot of object.

10. Crypto interface

IDL

[NoInterfaceObject]
interface GlobalCrypto {
  readonly attribute Crypto crypto;
};

Window implements GlobalCrypto;
WorkerGlobalScope implements GlobalCrypto;        
        
[Exposed=(Window,Worker)]
interface Crypto {
  readonly attribute SubtleCrypto subtle;
  ArrayBufferView getRandomValues(ArrayBufferView array);
};
        

10.1. Description

The Crypto interface represents an interface to general purpose cryptographic functionality including a cryptographically strong pseudo-random number generator seeded with truly random values.

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.
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 discouraged from using 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.

10.2. Methods and Parameters

10.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.3. Attributes

10.3.1. The subtle attribute

The subtle attribute provides an instance of the SubtleCrypto interface which provides low-level cryptographic primitives and algorithms.

11. 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

typedef (object or DOMString) AlgorithmIdentifier;

typedef AlgorithmIdentifier HashAlgorithmIdentifier;

dictionary Algorithm {
  required DOMString name;
};
        

11.1. Algorithm Dictionary Members

name
The name of the registered algorithm to use.

12. KeyAlgorithm dictionary

The KeyAlgorithm dictionary represents information about the contents of a given CryptoKey object.

IDL

dictionary KeyAlgorithm {
  required DOMString name
};
        

12.1. Description

This section is non-normative

The KeyAlgorithm dictionary is provided to aid in documenting how fixed, public properties of a CryptoKey are reflected back to an application. The actual dictionary type is never exposed to applications.

12.2. KeyAlgorithm dictionary members

name
The name of the algorithm used to generate the CryptoKey

13. CryptoKey interface

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

IDL

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

enum KeyUsage { "encrypt", "decrypt", "sign", "verify", "deriveKey", "deriveBits", "wrapKey", "unwrapKey" };

[Exposed=(Window,Worker)]
interface CryptoKey {
  readonly attribute KeyType type;
  readonly attribute boolean extractable;
  readonly attribute object algorithm;
  readonly attribute object usages;
};
        

13.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 CryptoKey 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 cryptographic operation.

13.2. Key interface data types

KeyType
The type of a key. The recognized key type values are "public", "private" and "secret". 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".
KeyUsage
A type of operation that may be performed using a key. The recognized key usage values are "encrypt", "decrypt", "sign", "verify", "deriveKey", "deriveBits", "wrapKey" and "unwrapKey".

13.3. CryptoKey internal slots

Every CryptoKey object has a set of internal slots that store information about the key. These slots are not exposed as part of this specification; they represent internal state that an implementation uses to implement this specification. The notational convention used in [ECMA-262] is re-used here; internal slots are identified by names enclosed in double square brackets [[ ]].

All CryptoKey objects have internal slots named [[type]], [[extractable]], [[algorithm]], [[algorithm_cached]], [[usages]], [[usages_cached]], and [[handle]].

The contents of the [[algorithm]] internal slot shall be, or be derived from, a KeyAlgorithm. The contents of the [[usages]] internal slot shall be of type Sequence<KeyUsage>.

The [[handle]] slot is an opaque type that contains whatever data the underlying cryptographic implementation uses to represent a logical key. Different cryptographic implementations may use different types, ranging from opaque identifiers represented as integers, pointer types, or structures that provide identifying information. These handles are never exposed to applications.

13.4. CryptoKey interface members

type
Reflects the [[type]] internal slot, which contains the type of the underlying key.
extractable
Reflects the [[extractable]] internal slot, which indicates whether or not the raw keying material may be exported by the application.
algorithm
Returns the cached ECMAScript object associated with the [[algorithm]] internal slot.
usages
Returns the cached ECMAScript object associated with the [[usages]] internal slot, which indicates which cryptographic operations are permissible to be used with this key.

13.5. Structured clone algorithm

When a user agent is required to obtain a structured clone of a CryptoKey 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 CryptoKey object to be cloned.
  2. Let output be a newly constructed CryptoKey object.
  3. Let the [[type]], [[extractable]], [[algorithm]], and [[usages]] internal slots of output be set to the result of invoking the internal structured clone algorithm recursively on the corresponding internal slots of input, with the slot contents as the new "input" argument and memory as the new "memory" argument.
  4. Let the [[handle]] internal slot of output refer to the same cryptographic key data represented by the [[handle]] internal slot of input.
Note
Implementation Note: When performing the structured clone algorithm in order to serialize a CryptoKey object, implementations must not allow the object to be deserialized as a different type. This is normatively required by the definition of structured clone, but it merits specific attention, as such deserialization may expose the contents of the [[handle]] internal slot, which in some implementations may contain cryptographic key data that should not be exposed to applications.

14. SubtleCrypto interface

IDL

enum KeyFormat { "raw", "spki", "pkcs8", "jwk" };

[Exposed=(Window,Worker)]
interface SubtleCrypto {
  Promise<any> encrypt(AlgorithmIdentifier algorithm,
                       CryptoKey key,
                       BufferSource data);
  Promise<any> decrypt(AlgorithmIdentifier algorithm,
                       CryptoKey key,
                       BufferSource data);
  Promise<any> sign(AlgorithmIdentifier algorithm,
                    CryptoKey key,
                    BufferSource data);
  Promise<any> verify(AlgorithmIdentifier algorithm,
                      CryptoKey key,
                      BufferSource signature,
                      BufferSource data);
  Promise<any> digest(AlgorithmIdentifier algorithm,
                      BufferSource data);

  Promise<any> generateKey(AlgorithmIdentifier algorithm,
                          boolean extractable,
                          sequence<KeyUsage> keyUsages );
  Promise<any> deriveKey(AlgorithmIdentifier algorithm,
                         CryptoKey baseKey,
                         AlgorithmIdentifier derivedKeyType,
                         boolean extractable,
                         sequence<KeyUsage> keyUsages );
  Promise<any> deriveBits(AlgorithmIdentifier algorithm,
                          CryptoKey baseKey,
                          unsigned long length);
  
  // TBD: ISSUE-35
  Promise<any> importKey(KeyFormat format,
                         (BufferSource or JsonWebKey) keyData,
                         AlgorithmIdentifier algorithm,
                         boolean extractable,
                         sequence<KeyUsage> keyUsages );
  Promise<any> exportKey(KeyFormat format, CryptoKey key);

  Promise<any> wrapKey(KeyFormat format,
                       CryptoKey key,
                       CryptoKey wrappingKey,
                       AlgorithmIdentifier wrapAlgorithm);
  Promise<any> unwrapKey(KeyFormat format,
                         BufferSource wrappedKey,
                         CryptoKey unwrappingKey,
                         AlgorithmIdentifier unwrapAlgorithm,
                         AlgorithmIdentifier unwrappedKeyAlgorithm,
                         boolean extractable,
                         sequence<KeyUsage> keyUsages );
};
        
Editorial note
  • ISSUE-35: The specification for wrapKey/unwrapKey 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.

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. Data Types

KeyFormat
Specifies a serialization format for a key. The recognized key format values are:
"raw"
An unformatted sequence of bytes. Intended for secret keys.
"pkcs8"
The DER encoding of the PrivateKeyInfo structure from RFC 5208.
"spki"
The DER encoding of the SubjectPublicKeyInfo structure from RFC 5280.
"jwk"
The key is a JsonWebKey dictionary encoded as a JavaScript object

14.3. Methods and Parameters

Note

All errors are reported asynchronously by rejecting the returned Promise. This includes Web IDL type mapping errors.

14.3.1. The encrypt method

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

  1. Let algorithm and key be the algorithm and key parameters passed to the encrypt method, respectively.

  2. Let data be the result of cloning the data of the data parameter passed to the encrypt method.

  3. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "encrypt".

  4. If an error occurred, return a Promise rejected with normalizedAlgorithm.

  5. Let promise be a new Promise.

  6. Return promise and asynchronously perform the remaining steps.

  7. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm.

  8. If the name member of normalizedAlgorithm is not equal to the name attribute of the [[algorithm]] internal slot of key then throw an InvalidAccessError.

  9. If the [[usages]] internal slot of key does not contain an entry that is "encrypt", then throw an InvalidAccessError.

  10. Let ciphertext be the result of performing the encrypt operation specified by normalizedAlgorithm using algorithm and key and with data as plaintext.

  11. Resolve promise with ciphertext.

14.3.2. The decrypt method

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

  1. Let algorithm and key be the algorithm and keyparameters passed to the decrypt method, respectively.

  2. Let data be the result of cloning the data of the data parameter passed to the decrypt method.

  3. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "decrypt".

  4. If an error occurred, return a Promise rejected with normalizedAlgorithm.

  5. Let promise be a new Promise.

  6. Return promise and asynchronously perform the remaining steps.

  7. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm.

  8. If the name member of normalizedAlgorithm is not equal to the name attribute of the [[algorithm]] internal slot of key then throw an InvalidAccessError.

  9. If the [[usages]] internal slot of key does not contain an entry that is "decrypt", then throw an InvalidAccessError.

  10. Let plaintext be the result of performing the decrypt operation specified by normalizedAlgorithm using key and algorithm and with data as ciphertext.

  11. Resolve promise with plaintext.

14.3.3. The sign method

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

  1. Let algorithm and key be the algorithm and key parameters passed to the sign method, respectively.

  2. Let data be the result of cloning the data of the data parameter passed to the sign method.

  3. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "sign".

  4. If an error occurred, return a Promise rejected with normalizedAlgorithm.

  5. Let promise be a new Promise.

  6. Return promise and asynchronously perform the remaining steps.

  7. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm.

  8. If the name member of normalizedAlgorithm is not equal to the name attribute of the [[algorithm]] internal slot of key then throw an InvalidAccessError.

  9. If the [[usages]] internal slot of key does not contain an entry that is "sign", then throw an InvalidAccessError.

  10. Let result be the result of performing the sign operation specified by normalizedAlgorithm using key and algorithm and with data as message.

  11. Resolve promise with result.

14.3.4. The verify method

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

  1. Let algorithm and key be the algorithm and key parameters passed to the verify method, respectively.

  2. Let signature be the result of cloning the data of the signature parameter passed to the verify method.

  3. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "verify".

  4. If an error occurred, return a Promise rejected with normalizedAlgorithm.

  5. Let data be the result of cloning the data of the data parameter passed to the verify method.

  6. Let promise be a new Promise.

  7. Return promise and asynchronously perform the remaining steps.

  8. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm.

  9. If the name member of normalizedAlgorithm is not equal to the name attribute of the [[algorithm]] internal slot of key then throw an InvalidAccessError.

  10. If the [[usages]] internal slot of key does not contain an entry that is "verify", then throw an InvalidAccessError.

  11. Let result be the result of performing the verify operation specified by normalizedAlgorithm using key, algorithm and signature and with data as message.

  12. Resolve promise with result.

14.3.5. The digest method

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

  1. Let algorithm be the algorithm parameter passed to the digest method.

  2. Let data be the result of cloning the data of the data parameter passed to the digest method.

  3. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "digest".

  4. If an error occurred, return a Promise rejected with normalizedAlgorithm.

  5. Let promise be a new Promise.

  6. Return promise and asynchronously perform the remaining steps.

  7. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm.

  8. Let result be the result of performing the digest operation specified by normalizedAlgorithm using algorithm, with data as message.

  9. Resolve promise with result.

14.3.6. The generateKey method

When invoked, generateKey MUST perform the following steps:

  1. Let algorithm, extractable and usages be the algorithm, extractable and keyUsages parameters passed to the generateKey method, respectively.

  2. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "generateKey".

  3. If an error occurred, return a Promise rejected with normalizedAlgorithm.

  4. Let promise be a new Promise.

  5. Return promise and asynchronously perform the remaining steps.

  6. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm.

  7. Let result be the result of executing the generate key operation specified by normalizedAlgorithm using algorithm, extractable and usages.

  8. If result is a CryptoKey object:

    If the [[type]] internal slot of result is "secret" or "private" and usages is empty, then throw a SyntaxError.

    If result is a CryptoKeyPair object:

    If the [[usages]] internal slot of the privateKey attribute of result is the empty sequence, then throw a SyntaxError.

  9. Resolve promise with result.

14.3.7. The deriveKey method

When invoked, deriveKey MUST perform the following steps:

  1. Let algorithm, baseKey, derivedKeyType, extractable and usages be the algorithm, baseKey, derivedKeyType, extractable and keyUsages parameters passed to the deriveKey method, respectively.

  2. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "deriveBits".

  3. If an error occurred, return a Promise rejected with normalizedAlgorithm.

  4. Let normalizedDerivedKeyAlgorithm be the result of normalizing an algorithm, with alg set to derivedKeyType and op set to "importKey".

  5. If an error occurred, return a Promise rejected with normalizedDerivedKeyAlgorithm.

  6. Let promise be a new Promise.

  7. Return promise and asynchronously perform the remaining steps.

  8. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm.

  9. If the name member of normalizedAlgorithm does not identify a registered algorithm that supports the derive bits operation, then throw a NotSupportedError.

  10. If the name member of normalizedDerivedKeyAlgorithm does not identify a registered algorithm that supports the get key length operation, then throw a NotSupportedError.

  11. If the name member of normalizedAlgorithm is not equal to the name attribute of the [[algorithm]] internal slot of baseKey then throw an InvalidAccessError.

  12. If the [[usages]] internal slot of baseKey does not contain an entry that is "deriveKey", then throw an InvalidAccessError.

  13. Let length be the result of executing the get key length algorithm specified by normalizedDerivedKeyAlgorithm using derivedKeyType.

  14. Let secret be the result of executing the derive bits operation specified by normalizedAlgorithm using key, algorithm and length.

  15. Let result be the result of executing the import key operation specified by normalizedDerivedKeyAlgorithm using "raw" as format, secret as keyData, derivedKeyType as algorithm and using extractable and usages.

  16. If the [[type]] internal slot of result is "secret" or "private" and usages is empty, then throw a SyntaxError.

  17. Resolve promise with result.

14.3.8. The deriveBits method

When invoked, deriveBits MUST perform the following steps:

  1. Let algorithm, baseKey and length, be the algorithm, baseKey and length parameters passed to the deriveBits method, respectively.

  2. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "deriveBits".

  3. If an error occurred, return a Promise rejected with normalizedAlgorithm.

  4. Let promise be a new Promise object.

  5. Return promise and asynchronously perform the remaining steps.

  6. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm.

  7. If the name member of normalizedAlgorithm is not equal to the name attribute of the [[algorithm]] internal slot of baseKey then throw an InvalidAccessError.

  8. If the [[usages]] internal slot of baseKey does not contain an entry that is "deriveBits", then throw an InvalidAccessError.

  9. Let result be a new ArrayBuffer containing the result of executing the derive bits operation specified by normalizedAlgorithm using baseKey, algorithm and length.

  10. Resolve promise with result.

14.3.9. The importKey method

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

  1. Let format, algorithm, extractable and usages, be the format, algorithm, extractable and keyUsages parameters passed to the importKey method, respectively.

  2. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "importKey".

  3. If an error occurred, return a Promise rejected with normalizedAlgorithm.

  4. Let promise be a new Promise.

  5. Return promise and asynchronously perform the remaining steps.

  6. If format is equal to the string "raw", "pkcs8", or "spki":
    1. If the keyData parameter passed to the importKey method is a JsonWebKey dictionary, throw a TypeError.

    2. Let keyData be the result of cloning the data of the keyData parameter passed to the importKey method.

    If format is equal to the string "jwk":
    1. If the keyData parameter passed to the importKey method is not a JsonWebKey dictionary, throw a TypeError.

    2. Let keyData be the keyData parameter passed to the importKey method.

  7. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm.

  8. Let result be the CryptoKey object that results from performing the import key operation specified by normalizedAlgorithm using keyData, algorithm, format, extractable and usages.

  9. If the [[type]] internal slot of result is "secret" or "private" and usages is empty, then throw a SyntaxError.

  10. Set the [[extractable]] internal slot of result to extractable.

  11. Set the [[usages]] internal slot of result to the normalized value of usages.

  12. Resolve promise with result.

Note

This note is non-normative.

For structured key formats, "spki", "pks8" and "jwk", fields that are not explicitly referred to in the key import procedures for an algorithm are ignored.

14.3.10. The exportKey method

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

  1. Let format and key be the format and key parameters passed to the exportKey method, respectively.

  2. Let promise be a new Promise.

  3. Return promise and asynchronously perform the remaining steps.

  4. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm.

  5. If the name member of of the [[algorithm]] internal slot of key does not identify a registered algorithm that supports the export key operation, then throw a NotSupportedError.

  6. If the [[extractable]] internal slot of key is false, then throw an InvalidAccessError.

  7. Let result be the result of performing the export key operation specified by the [[algorithm]] internal slot of key using key and format.

  8. Resolve promise with result.

14.3.11. The wrapKey method

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

  1. Let format, key, wrappingKey and algorithm be the format, key, wrappingKey and wrapAlgorithm parameters passed to the wrapKey method, respectively.

  2. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "wrapKey".

  3. If an error occurred, let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "encrypt".

  4. If an error occurred, return a Promise rejected with normalizedAlgorithm.

  5. Let promise be a new Promise.

  6. Return promise and asynchronously perform the remaining steps.

  7. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm.

  8. If the name member of normalizedAlgorithm does not identify a registered algorithm that supports the encrypt or wrap key operation, then throw a NotSupportedError.

  9. If the name member of normalizedAlgorithm is not equal to the name attribute of the [[algorithm]] internal slot of wrappingKey then throw an InvalidAccessError.

  10. If the [[usages]] internal slot of wrappingKey does not contain an entry that is "wrapKey", then throw an InvalidAccessError.

  11. If the algorithm identified by the [[algorithm]] internal slot of key does not support the export key operation, then throw a NotSupportedError.

  12. If the [[extractable]] internal slot of key is false, then throw an InvalidAccessError.

  13. Let key be the result of performing the export key operation specified the [[algorithm]] internal slot of key using key and format.

  14. If format is equal to the strings "raw", "pkcs8", or "spki":
    Set bytes be set to key.
    If format is equal to the string "jwk":
    1. Convert key to an ECMAScript Object, as specified in [ WebIDL].

    2. Let json be the result of representing key as a UTF-16 string conforming to the JSON grammar; for example, by executing the JSON.stringify algorithm specified in ECMA262.

    3. Let bytes be the byte sequence the results from converting json, a JavaScript String comprised of UTF-16 code points, to UTF-8 code points.

    Note

    This note is non-normative.

    The key wrapping operations for some algorithms place constraints on the payload size. For example AES-KW requires the payload to be a multiple of 8 bytes in length and RSA-OAEP places a restriction on the length. For key formats that offer flexibility in serialization of a given key (for example JWK), implementations may choose to adapt the serialization to the constraints of the wrapping algorithm. This is why JSON.stringify is not normatively required, as otherwise it would prohibit implementations from introducing added padding.

  15. If normalizedAlgorithm supports the wrap key operation:

    Let result be the result of performing the wrap key operation specified by normalizedAlgorithm using algorithm, wrappingKey as key and bytes as plaintext.

    Otherwise, if normalizedAlgorithm supports the encrypt operation:

    Let result be the result of performing the encrypt operation specified by normalizedAlgorithm using algorithm, wrappingKey as key and bytes as plaintext.

    Otherwise:
    throw a NotSupportedError.
  16. Resolve promise with result.

14.3.12. The unwrapKey method

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

  1. Let format, unwrappingKey, algorithm, unwrappedKeyAlgorithm, extractable and usages, be the format, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable and keyUsages parameters passed to the unwrapKey method, respectively.

  2. Let wrappedKey be the result of cloning the data of the data parameter passed to the unwrapKey method.

  3. Let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "unwrapKey".

  4. If an error occurred, let normalizedAlgorithm be the result of normalizing an algorithm, with alg set to algorithm and op set to "decrypt".

  5. If an error occurred, return a Promise rejected with normalizedAlgorithm.

  6. Let normalizedKeyAlgorithm be the result of normalizing an algorithm, with alg set to unwrappedKeyAlgorithm and op set to "importKey".

  7. If an error occurred, return a Promise rejected with normalizedKeyAlgorithm.

  8. Let promise be a new Promise.

  9. Return promise and asynchronously perform the remaining steps.

  10. If the following steps or referenced procedures say to throw an error, reject promise with the returned error and then terminate the algorithm.

  11. If the name member of normalizedAlgorithm is not equal to the name attribute of the [[algorithm]] internal slot of unwrappingKey then throw an InvalidAccessError.

  12. If the [[usages]] internal slot of unwrappingKey does not contain an entry that is "unwrapKey", then throw an InvalidAccessError.

  13. If normalizedAlgorithm supports an unwrap key operation:
    Let key be the result of performing the unwrap key operation specified by normalizedAlgorithm using algorithm, unwrappingKey as key and wrappedKey as ciphertext.
    Otherwise, if normalizedAlgorithm supports a decrypt operation:
    Let key be the result of performing the decrypt operation specified by normalizedAlgorithm using algorithm, unwrappingKey as key and wrappedKey as ciphertext.
    Otherwise:
    throw a NotSupportedError.
  14. If format is equal to the strings "raw", "pkcs8", or "spki":
    Set bytes be set to key.
    If format is equal to the string "jwk":
    Let bytes be the result of executing the parse a JWK algorithm, withe key as the data to be parsed.
  15. Let result be the result of performing the import key operation specified by normalizedKeyAlgorithm using unwrappedKeyAlgorithm as algorithm, format, usages and extractable and with bytes as keyData.

  16. If the [[type]] internal slot of result is "secret" or "private" and usages is empty, then throw a SyntaxError.

  17. Set the [[extractable]] internal slot of result to extractable.

  18. Set the [[usages]] internal slot of result to the normalized value of usages.

  19. Resolve promise with result.

14.4. Exceptions

The methods of the SubtleCrypto interface return errors by rejecting the returned promise with a predefined exception defined in ECMAScript [ECMA-262] or DOMException. The following predefined exceptions are used: TypeError. The following DOMException types from [DOM4] are used:

Type Message (optional)
NotSupportedError The algorithm is not supported
SyntaxError A required parameter was missing or out-of-range
InvalidStateError The requested operation is not valid for the current state of the provided key.
InvalidAccessError The requested operation is not valid for the provided key
UnknownError The operation failed for an unknown transient reason (e.g. out of memory)
DataError Data provided to an operation does not meet requirements
OperationError The operation failed for an operation-specific reason

When this specification says to throw an error, the user agent must throw an error as described in [WebIDL]. When this occurs in a sub-algorithm, this results in termination of execution of the sub-algorithm and all ancestor algorithms until one is reached that explicitly describes procedures for catching exceptions.

15. JsonWebKey dictionary

IDL

dictionary RsaOtherPrimesInfo {
  // The following fields are defined in Section 6.3.2.7 of JSON Web Algorithms
  DOMString r;
  DOMString d;
  DOMString t;
};

dictionary JsonWebKey {
  // The following fields are defined in Section 3.1 of JSON Web Key
  DOMString kty;
  DOMString use;
  sequence<DOMString> key_ops;
  DOMString alg;

  // The following fields are defined in JSON Web Key Parameters Registration
  boolean ext;

  // The following fields are defined in Section 6 of JSON Web Algorithms
  DOMString crv;
  DOMString x;
  DOMString y;
  DOMString d;
  DOMString n;
  DOMString e;
  DOMString p;
  DOMString q;
  DOMString dp;
  DOMString dq;
  DOMString qi;
  sequence<RsaOtherPrimesInfo> oth;
  DOMString k;
};
        

Description

The following section is non-normative

The JsonWebKey dictionary provides a way to represent and exchange cryptographic keys represented by the JSON Web Key structure, while allowing native and efficient use within Web Cryptography API applications.

16. BigInteger

IDL

typedef Uint8Array BigInteger;
        

The BigInteger typedef is a Uint8Array that holds an arbitrary magnitude unsigned integer in big-endian order. Values read from the API SHALL have minimal typed array length (that is, at most 7 leading zero bits, except the value 0 which shall have length 8 bits). The API SHALL accept values with any number of leading zero bits, including the empty array, which represents zero.

Note
Implementation Note: Since the integer is unsigned, the highest order bit is NOT a sign bit. Implementors should take care when mapping to big integer implementations that expected signed integers.

17. CryptoKeyPair dictionary

IDL

dictionary CryptoKeyPair {
  CryptoKey publicKey;
  CryptoKey privateKey;
};
        

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

18. Algorithms

18.1. Overview

This section is non-normative.

In addition to providing a common interface to perform cryptographic operations, by way of the SubtleCrypto interface, this specification also provides descriptions for a variety of algorithms that authors may wish to use and that User Agents may choose to implement. This includes a selection of commonly-deployed symmetric and asymmetric algorithms, key derivation mechanisms, and methods for wrapping and unwrapping keys. Further, this specification defines a process to allow additional specifications to introduce additional cryptographic algorithms.

18.2. Concepts

18.2.1. Naming

Every cryptographic algorithm defined for use with the Web Cryptography API MUST have a unique name, referred to as its recognized algorithm name, such that no other specification defines the same case-sensitive string for use with the Web Cryptography API.

18.2.2. Supported Operations

Every cryptographic algorithm defined for use with the Web Cryptography API has a list of supported operations, which are a set of sub-algorithms to be invoked by the SubtleCrypto interface in order to perform the desired cryptographic operation. This specification makes use of the following operations:

  • encrypt
  • decrypt
  • sign
  • verify
  • deriveBits
  • wrapKey
  • unwrapKey
  • generateKey
  • importKey
  • exportKey
  • getLength

If a given algorithm specification does not list a particular operation as supported, or explicitly lists an operation as not-supported, then the User Agent MUST behave as if the invocation of the sub-algorithm threw a NotSupportedError.

18.2.3. Normalization

Every cryptographic algorithm defined for use with the Web Cryptography API MUST define, for every supported operation, the IDL type to use for algorithm normalization, as well as the IDL type or types of the return values of the sub-algorithms.

18.3. Specification Conventions

Every cryptographic algorithm definition within this specification employs the following specification conventions. A section, titled "Registration", will include the recognized algorithm name. Additionally, it includes a table, which will list each of the supported operations as rows, identified by the Operation column. The contents of the Parameters column for a given row will contain the IDL type to use for algorithm normalization for that operation, and the contents of the Result column for that row indicate the IDL type that results from performing the supported operation.

If a conforming User Agent implements an algorithm, it MUST implement all of the supported operations and MUST return the IDL type specified.

Additionally, upon initialization, conforming User Agents must perform the define an algorithm steps for each of the supported operations, registering their IDL parameter type as indicated.

18.4. Algorithm Normalization

18.4.1. Description

This section is non-normative

The AlgorithmIdentifier typedef permits algorithms to either be specified as a DOMString or an object. The usage of DOMString is to permit authors a short-hand for noting algorithms that have no parameters (e.g. SHA-1). The usage of object is to allow an Algorithm (or appropriate subclass) to be specified, which contains all of the associated parameters for an object.

Because of this, it's necessary to define the algorithm for converting an AlgorithmIdentifier into an appropriate dictionary that is usable with this API. This algorithm must be extensible, so as to allow new cryptographic algorithms to be added, and consistent, so that Web IDL type mapping can occur before any control is returned to the calling script, which would potentially allow the mutation of parameters or the script environment.

18.4.2. Internal State Objects

This specification makes use of an internal object, [[supportedAlgorithms]]. This internal object is not exposed to applications.

Because this value is not exposed to applications, the exact type is not specified. It is only required to behave as an associative container of key/value pairs, where comparisons of keys are performed in a case-sensitive manner.

The initial contents of this internal object are as follows:

  1. For each value, v in the List of supported operations, set the v key of the internal object [[supportedAlgorithms]] to a new associative container.

18.4.3. Defining an Algorithm

The define an algorithm algorithm is used by specification authors to indicate how a user agent should normalize arguments for a particular algorithm. Its input is an algorithm name alg, represented as a DOMString, operation name op, represented as a DOMString, and desired IDL dictionary type type. The algorithm behaves as follows:

  1. Let registeredAlgorithms be the associative container stored at the op key of [[supportedAlgorithms]]..
  2. Set the alg key of registeredAlgorithms to the IDL dictionary type type.

18.4.4. Normalizing an algorithm

The normalize an algorithm algorithm defines a process for coercing inputs to a targeted IDL dictionary type, after Web IDL conversion has occurred. It is designed to be extensible, to allow future specifications to define additional algorithms, as well as safe for use with Promises. Its input is an operation name op and an AlgorithmIdentifier alg. Its output is either an IDL dictionary type or an error. It behaves as follows:

If alg is an instance of a DOMString:

Return the result of running the normalize an algorithm algorithm, with the alg set to a new KeyAlgorithm dictionary whose name attribute is alg, and with the op set to op.

If alg is an object:
  1. Let registeredAlgorithms be the associative container stored at the op key of [[supportedAlgorithms]].
  2. Let initialAlg be the result of converting the ECMAScript object represented by alg to the IDL dictionary type Algorithm, as defined by [WebIDL].
  3. If an error occurred, return the error and terminate this algorithm.
  4. Let algName be the value of the name attribute of initialAlg.
  5. If registeredAlgorithms contains a key that is a case-insensitive string match for algName:
    1. Set algName to the value of the matching key.

    2. Let desiredType be the IDL dictionary type stored at algName in registeredAlgorithms.

    Otherwise:
    Return a new NotSupportedError and terminate this algorithm.
  6. Let normalizedAlgorithm be the result of converting the ECMAScript object represented by alg to the IDL dictionary type desiredType, as defined by [WebIDL].
  7. Set the name attribute of normalizedAlgorithm to algName.
  8. If an error occurred, return the error and terminate this algorithm.
  9. Let dictionaries be a list consisting of the IDL dictionary type desiredType and all of desiredType's inherited dictionaries, in order from least to most derived.
  10. For each dictionary dictionary in dictionaries:

    1. For each dictionary member member declared on dictionary, in order:

      1. Let key be the identifier of member.
      2. Let idlValue be the value of the dictionary member with key name of key on normalizedAlgorithm.
      3. If member is of the type BufferSource and is present:
        Set the dictionary member on normalizedAlgorithm with key name key to a clone of idlValue, replacing the current value.
        If member is of the type HashAlgorithmIdentifier:
        Set the dictionary member on normalizedAlgorithm with key name key to the result of normalizing an algorithm, with the alg set to idlValue and the op set to "digest".
        If member is of the type AlgorithmIdentifier:
        Set the dictionary member on normalizedAlgorithm with key name key to the result of normalizing an algorithm, with the alg set to idlValue and the op set to the operation defined by the specification that definines the algorithm identified by algName.
      4. If an error occurred, return the error and terminate this algorithm.
  11. Return normalizedAlgorithm.

18.5. Recommendations

This section is non-normative.

18.5.1. For Authors

As this API is meant to be extensible, in order to keep up with future developments within cryptography, there are no algorithms that conforming user agents are required to implement. As such, authors should check to see what algorithms are currently recommended and supported by implementations.

As highlighted in the Security Considerations, even cryptographic algorithms that might be considered strong for one purpose may be insufficient when used with another purpose. Authors should therefore proceed with extreme caution before inventing new cryptographic protocols.

Additionally, this specification includes several algorithms which, in their default usage, can result in cryptographic vulnerabilities. While these concerns may be mitigated, such as through the combination and composition with additional algorithms provided by this specification, authors should proceed with caution and review the relevant cryptographic literature before using a given algorithm. The inclusion of algorithms within this specification is not an indicator of their suitability for any or all purpose, and instead merely serve to provide as a specification for how a conforming User Agent must implement the given algorithm, if it choses to implement the algorithm.

18.5.2. For Implementers

In order to promote interoperability for developers, this specification includes a list of suggested algorithms. These are considered to be the most widely used algorithms in practice at the time of writing, and therefore provide a good starting point for initial implementations of this specification. The suggested algorithms are:

19. Algorithm Overview

The following section is non-normative.

The table below contains an overview of the algorithms described within this specification, as well as the set of subtlecrypto methods the algorithm may be used with. In order for an algorithm to be used with a method the corresponding operation or operations, as defined in the procedures for the method, must be defined in the algorithm specification. Note that this mapping of methods to underlying operations is not one-to-one:

Application developers and script authors should not interpret this table as a recommendation for the use of particular algorithms. Instead, it simply documents what methods areA supported. Authors should refer to the Security considerations for authors section of this document to better understand the risks and concerns that may arise when using certain 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.

Algorithm name encrypt decrypt sign verify digest generateKey deriveKey deriveBits importKey exportKey wrapKey unwrapKey
RSASSA-PKCS1-v1_5
RSA-PSS
RSA-OAEP
ECDSA
ECDH
AES-CTR
AES-CBC
AES-CMAC
AES-GCM
AES-CFB
AES-KW
HMAC
DH
SHA-1
SHA-256
SHA-384
SHA-512
CONCAT
HKDF-CTR
PBKDF2

20. RSASSA-PKCS1-v1_5

20.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] and using the SHA hash functions defined in this specification.

Other specifications may specify the use of additional hash algorithms with RSASSA-PKCS1-v1_5. Such specifications myst define the digest operations for the additional hash algorithms and key import steps and key export steps for RSASSA-PKCS1-v1_5.

20.2. Registration

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

Operation Parameters Result
sign None ArrayBuffer
verify None boolean
generateKey RsaHashedKeyGenParams CryptoKeyPair
importKey RsaHashedImportParams CryptoKey
exportKey None object

20.3. RsaKeyGenParams dictionary

IDL

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

20.4. RsaHashedKeyGenParams dictionary

IDL

dictionary RsaHashedKeyGenParams : RsaKeyGenParams {
  // The hash algorithm to use 
  required HashAlgorithmIdentifier hash;
};
          

20.5. RsaKeyAlgorithm dictionary

IDL

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

20.6. RsaHashedKeyAlgorithm dictionary

IDL

dictionary RsaHashedKeyAlgorithm : RsaKeyAlgorithm {
  // The hash algorithm that is used with this key
  required KeyAlgorithm hash;
};
          

20.7. RsaHashedImportParams dictionary

IDL

dictionary RsaHashedImportParams {
  // The hash algorithm to use
  required HashAlgorithmIdentifier hash;
};
          
Editorial note

Should this be folded into RsaHashedKeyGenParams and rely on the optional nature of the dictionary fields?

20.8. Operations

Sign
  1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

  2. Perform the signature generation operation defined in Section 8.2 of [RFC3447] with the key represented by the [[handle]] internal slot of key as the signer's private key and the contents of message as M and using the hash function specified in the hash attribute of the [[algorithm]] internal slot of key as the Hash option for the EMSA-PKCS1-v1_5 encoding method.

  3. If performing the operation results in an error, then throw an OperationError.

  4. Let signature be the value S that results from performing the operation.

Verify
  1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

  2. Perform the signature verification operation defined in Section 8.2 of [RFC3447] with the key represented by the [[handle]] internal slot of key as the signer's RSA public key and the contents of message as M and the contents of signature as S and using the hash function specified in the hash attribute of the [[algorithm]] internal slot of key as the Hash option for the EMSA-PKCS1-v1_5 encoding method.

  3. If performing the operation results in an error, then throw an OperationError.

  4. Let result be a boolean with value true if the result of the operations was "valid signature" and a boolean with value false otherwise.

Generate Key
  1. If usages contains an entry which is not "sign" or "verify", then throw a SyntaxError.

  2. Generate an RSA key pair, as defined in [RFC3447], with RSA modulus length equal to the modulusLength attribute of normalizedAlgorithm and RSA public exponent equal to the publicExponent attribute of normalizedAlgorithm.

  3. If generation of the key pair fails, then throw an OperationError.

  4. Let algorithm be a new RsaHashedKeyAlgorithm dictionary.

  5. Set the name attribute of algorithm to "RSASSA-PKCS1-v1_5".

  6. Set the modulusLength attribute of algorithm to equal the modulusLength attribute of normalizedAlgorithm.

  7. Set the publicExponent attribute of algorithm to equal the publicExponent attribute of normalizedAlgorithm.

  8. Set the hash attribute of algorithm to equal the hash member of normalizedAlgorithm.

  9. Let publicKey be a new CryptoKey object representing the public key of the generated key pair.

  10. Set the [[type]] internal slot of publicKey to "public"

  11. Set the [[algorithm]] internal slot of publicKey to algorithm.

  12. Set the [[extractable]] internal slot of publicKey to true.

  13. Set the [[usages]] internal slot of publicKey to be the usage intersection of usages and [ "verify" ].

  14. Let privateKey be a new CryptoKey object representing the private key of the generated key pair.

  15. Set the [[type]] internal slot of privateKey to "private"

  16. Set the [[algorithm]] internal slot of privateKey to algorithm.

  17. Set the [[extractable]] internal slot of privateKey to extractable.

  18. Set the [[usages]] internal slot of privateKey to be the usage intersection of usages and [ "sign" ].

  19. Let result be a new CryptoKeyPair dictionary.

  20. Set the publicKey attribute of result to be publicKey.

  21. Set the privateKey attribute of result to be privateKey.

  22. Return the result of converting result to an ECMAScript Object, as defined by [WebIDL].

Editorial note

TODO: Specify the mapping between key.algorithm.hash and the appropriate Hash functions (and back to OID).

Import Key
  1. Let keyData be the key data to be imported.

  2. If format is "spki":
    1. If usages contains an entry which is not "verify", then throw a SyntaxError.

    2. Let spki be the result of running the parse a subjectPublicKeyInfo algorithm over keyData.

    3. If an error occurred while parsing, then throw a DataError.

    4. Let hash be undefined.

    5. Let alg be the algorithm object identifier field of the algorithm AlgorithmIdentifier field of spki.

    6. If alg is equivalent to the rsaEncryption OID defined in Section 2.3.1 of RFC 3279:

      Let hash be undefined.

      If alg is equivalent to the sha1WithRSAEncryption OID defined in Section A.2.4 of RFC 3279:

      Let hash be the string "SHA-1".

      If alg is equivalent to the sha256WithRSAEncryption OID defined in Section A.2.4 of RFC 3279:

      Let hash be the string "SHA-256".

      If alg is equivalent to the sha384WithRSAEncryption OID defined in Section A.2.4 of RFC 3279:

      Let hash be the string "SHA-384".

      If alg is equivalent to the sha512WithRSAEncryption OID defined in Section A.2.4 of RFC 3279:

      Let hash be the string "SHA-512".

      Otherwise:
      1. Perform any key import steps defined by other applicable specifications, passing format, spki and obtaining hash.

      2. If an error occured or there are no applicable specifications, throw a DataError.

    7. If hash is not undefined:
      1. Let normalizedHash be the result of normalize an algorithm with alg set to hash and op set to digest.

      2. If normalizedHash is not equal to the hash member of normalizedAlgorithm, throw a DataError.

    8. Let publicKey be the result of performing the parse an ASN.1 structure algorithm, with data as the subjectPublicKeyInfo field of spki, structure as the RSAPublicKey structure specified in Section A.1.1 of RFC 3447, and exactData set to true.

    9. If an error occurred while parsing, then throw a DataError.

    10. Let key be a new CryptoKey object that represents the RSA public key identified by publicKey.

    11. Set the [[type]] internal slot of key to "public"

    If format is "pkcs8":
    1. If usages contains an entry which is not "sign" then throw a SyntaxError.

    2. Let privateKeyInfo be the result of running the parse a privateKeyInfo algorithm over keyData.

    3. If an error occurred while parsing, then throw a DataError.

    4. Let hash be undefined.

    5. Let alg be the algorithm object identifier field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo.

    6. If alg is equivalent to the rsaEncryption OID defined in Section 2.3.1 of RFC 3279:

      Let hash be undefined.

      If alg is equivalent to the sha1WithRSAEncryption OID defined in Section A.2.4 of RFC 3279:

      Let hash be the string "SHA-1".

      If alg is equivalent to the sha256WithRSAEncryption OID defined in Section A.2.4 of RFC 3279:

      Let hash be the string "SHA-256".

      If alg is equivalent to the sha384WithRSAEncryption OID defined in Section A.2.4 of RFC 3279:

      Let hash be the string "SHA-384".

      If alg is equivalent to the sha512WithRSAEncryption OID defined in Section A.2.4 of RFC 3279:

      Let hash be the string "SHA-512".

      Otherwise:
      1. Perform any key import steps defined by other applicable specifications, passing format, privateKeyInfo and obtaining hash.

      2. If an error occured or there are no applicable specifications, throw a DataError.

    7. If hash is not undefined:
      1. Let normalizedHash be the result of normalize an algorithm with alg set to hash and op set to digest.

      2. If normalizedHash is not equal to the hash member of normalizedAlgorithm, throw a DataError.

    8. Let rsaPrivateKey be the result of performing the parse an ASN.1 structure algorithm, with data as the privateKey field of privateKeyInfo, structure as the RSAPrivateKey structure specified in Section A.1.2 of RFC 3447, and exactData set to true.

    9. If an error occurred while parsing, then throw a DataError.

    10. Let key be a new CryptoKey object that represents the RSA private key identified by rsaPrivateKey.

    11. Set the [[type]] internal slot of key to "private"

    If format is "jwk":
    1. Let jwk be the JsonWebKey dictionary represented by keyData.

    2. If the "d" field of jwk is present and usages contains an entry which is not "sign", or, if the "d" field of jwk is not present and usages contains an entry which is not "verify" then throw a SyntaxError.

    3. If the "kty" field of jwk is not a case-sensitive string match to "RSA", then throw a DataError.

    4. If the "use" field of jwk is present, and is not a case-sensitive string match to "sig", then throw a DataError.

    5. If the "key_ops" field of jwk is present, and is invalid according to the requirements of JSON Web Key or does not contain all of the specified usages values, then throw a DataError.

    6. Let hash be a be a string whose initial value is undefined.

    7. If the "alg" field of jwk is not present:

      Let hash be undefined.

      If the "alg" field is equal to the string "RS1":

      Let hash be the string "SHA-1".

      If the "alg" field is equal to the string "RS256":

      Let hash be the string "SHA-256".

      If the "alg" field is equal to the string "RS384":

      Let hash be the string "SHA-384".

      If the "alg" field is equal to the string "RS512":

      Let hash be the string "SHA-512".

      Otherwise:
      1. Perform any key import steps defined by other applicable specifications, passing format, jwk and obtaining hash.

      2. If an error occured or there are no applicable specifications, throw a DataError.

    8. If hash is not undefined:
      1. Let normalizedHash be the result of normalize an algorithm with alg set to hash and op set to digest.

      2. If normalizedHash is not equal to the hash member of normalizedAlgorithm, throw a DataError.

    9. If the "d" field of jwk is present:
      1. If jwk does not meet the requirements of Section 6.3.2 of JSON Web Algorithms, then throw a DataError.

      2. Let key be a new CryptoKey object that represents the RSA private key identified by interpreting jwk according to Section 6.3.2 of JSON Web Algorithms.

      3. Set the [[type]] internal slot of key to "private"

      Otherwise:
      1. If jwk does not meet the requirements of Section 6.3.1 of JSON Web Algorithms, then throw a DataError.

      2. Let key be a new CryptoKey object that represents the RSA public key identified by interpreting jwk according to Section 6.3.1 of JSON Web Algorithms.

      3. Set the [[type]] internal slot of key to "public"

    Otherwise:
    throw a NotSupportedError.
  3. Let algorithm be a new RsaHashedKeyAlgorithm dictionary.

  4. Set the name attribute of algorithm to "RSASSA-PKCS1-v1_5"

  5. Set the modulusLength attribute of algorithm to the length, in bits, of the RSA public modulus.

  6. Set the publicExponent attribute of algorithm to the BigInteger representation of the RSA public exponent.

  7. Set the hash attribute of algorithm to the hash member of normalizedAlgorithm.

  8. Set the [[algorithm]] internal slot of key to algorithm.

  9. Return key.

Export Key
  1. Let key be the key to be exported.

  2. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  3. If format is "spki"
    1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

    2. Let data be an instance of the subjectPublicKeyInfo ASN.1 structure defined in RFC 5280 with the following properties:

      • Set the algorithm field to an AlgorithmIdentifier ASN.1 type with the following properties:

        • Set the algorithm field to the OID 1.2.840.113549.1.1

        • Set the params field to the ASN.1 type NULL.

      • Set the subjectPublicKey field to the result of DER-encoding an RSAPublicKey ASN.1 type, as defined in RFC 3447, Appendix A.1.1, that represents the RSA public key represented by the [[handle]] internal slot of key

    3. Let result be a new ArrayBuffer containing data.

    If format is "pkcs8":
    1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

    2. Let data be the result of encoding a privateKeyInfo structure with the following properties:

      • Set the version field to 0.

      • Set the privateKeyAlgorithm field to a PrivateKeyAlgorithmIdentifier ASN.1 type with the following properties:

        • Set the algorithm field to the OID 1.2.840.113549.1.1

        • Set the params field to the ASN.1 type NULL.

      • Set the privateKey field to the result of DER-encoding an RSAPrivateKey ASN.1 type, as defined in RFC 3447, Appendix A.1.2, that represents the RSA private key represented by the [[handle]] internal slot of key

        Editorial note
        RFC 5208 specifies that the encoding of this field should be BER encoded in Section 5 (as a "for example"). However, to avoid requiring WebCrypto implementations support BER-encoding and BER-decoding, only DER encodings are produced or accepted.
    3. Let result be a new ArrayBuffer containing data.

    If format is "jwk":
    • Let jwk be a new JsonWebKey dictionary.

    • Set the kty attribute of jwk to the string "RSA".

    • Let hash be the name attribute of the hash attribute of key.

    • If hash is "SHA-1":

      Set the alg attribute of jwk to the string "RS1".

      If hash is "SHA-256":

      Set the alg attribute of jwk to the string "RS256".

      If hash is "SHA-384":

      Set the alg attribute of jwk to the string "RS384".

      If hash is "SHA-512":

      Set the alg attribute of jwk to the string "RS512".

      Otherwise:
      1. Perform any key export steps defined by other applicable specifications, passing format, key and obtaining alg.

      2. If an error occured or there are no applicable specifications, throw a NotSupportedError.

      3. Set the alg attribute of jwk to alg.

    • Set the attributes n and e of jwk according to the corresponding definitions in JSON Web Algorithms, Section 6.3.1.

    • If the [[type]] internal slot of key is "private":
      1. Set the attributes named d, p, q, dp, dq, and qi of jwk according to the corresponding definitions in JSON Web Algorithms, Section 6.3.2.

      2. If the underlying RSA private key represented by the [[handle]] internal slot of key is represented by more than two primes, set the attribute named oth of jwk according to the corresponding definition in JSON Web Algorithms, Section 6.3.2.7

    • Set the key_ops attribute of jwk to the usages attribute of key.

    • Set the ext attribute of jwk to the [[extractable]] internal slot of key.

    • Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise

    throw a NotSupportedError.

  4. Return result.

21. RSA-PSS

21.1. Description

The "RSA-PSS" algorithm identifier is used to perform signing and verification using the RSASSA-PSS algorithm specified in [RFC3447], using the SHA hash functions defined in this specification and the mask generation formula MGF1.

Other specifications may specify the use of additional hash algorithms with RSASSA-PSS. Such specifications must define the digest operation for the additional hash algorithms and key import steps and key export steps for RSASSA-PSS.

21.2. Registration

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

Operation Parameters Result
sign RsaPssParams ArrayBuffer
verify RsaPssParams boolean
generateKey RsaHashedKeyGenParams CryptoKeyPair
importKey RsaHashedImportParams CryptoKey
exportKey None object

21.3. RsaPssParams dictionary

IDL

dictionary RsaPssParams : Algorithm {
// The desired length of the random salt
[EnforceRange] required unsigned long saltLength;
};
          

21.4. Operations

Sign
  1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

  2. Perform the signature generation operation defined in Section 8.1 of [RFC3447] with the key represented by the [[handle]] internal slot of key as the signer's private key, K, and the contents of message as the message to be signed, M, and using the hash function specified by the hash attribute of the [[algorithm]] internal slot of key as the Hash option, MGF1 (defined in Section B.2.1 of [RFC3447]) as the MGF option and the saltLength member of normalizedAlgorithm as the salt length option for the EMM-PSS-ENCODE operation.

  3. If performing the operation results in an error, then throw an OperationError.

  4. Let signature be a new ArrayBuffer containing the signature, S, that results from performing the operation.

Verify
  1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

  2. Perform the signature verification operation defined in Section 8.1 of [RFC3447] with the key represented by the [[handle]] internal slot of key as the signer's RSA public key and the contents of message as M and the contents of signature as S and using the hash function specified by the hash attribute of the [[algorithm]] internal slot of key as the Hash option, MGF1 (defined in Section B.2.1 of [RFC3447]) as the MGF option and the saltLength member of normalizedAlgorithm as the salt length option for the EMSA-PSS-VERIFY operation.

  3. If performing the operation results in an error, then throw an OperationError.

  4. Let result be a boolean with value true if the result of the operation was "valid signature" and a boolean with value false otherwise.

Generate Key
  1. If usages contains an entry which is not "sign" or "verify", then throw a SyntaxError.

  2. Generate an RSA key pair, as defined in [RFC3447], with RSA modulus length equal to the modulusLength member of normalizedAlgorithm and RSA public exponent equal to the publicExponent member of normalizedAlgorithm.

  3. If performing the operation results in an error, then throw an OperationError.

  4. Let algorithm be a new RsaHashedKeyAlgorithm dictionary.

  5. Set the name attribute of algorithm to "RSA-PSS".

  6. Set the modulusLength attribute of algorithm to equal the modulusLength member of normalizedAlgorithm.

  7. Set the publicExponent attribute of algorithm to equal the publicExponent member of normalizedAlgorithm.

  8. Set the hash attribute of algorithm to equal the hash member of normalizedAlgorithm.

  9. Let publicKey be a new CryptoKey object representing the public key of the generated key pair.

  10. Set the [[type]] internal slot of publicKey to "public"

  11. Set the [[algorithm]] internal slot of publicKey to algorithm.

  12. Set the [[extractable]] internal slot of publicKey to true.

  13. Set the [[usages]] internal slot of publicKey to be the usage intersection of usages and [ "verify" ].

  14. Let privateKey be a new CryptoKey object representing the private key of the generated key pair.

  15. Set the [[type]] internal slot of privateKey to "private"

  16. Set the [[algorithm]] internal slot of privateKey to algorithm.

  17. Set the [[extractable]] internal slot of privateKey to extractable.

  18. Set the [[usages]] internal slot of privateKey to be the usage intersection of usages and [ "sign" ].

  19. Let result be a new CryptoKeyPair dictionary.

  20. Set the publicKey attribute of result to publicKey.

  21. Set the privateKey attribute of result to privateKey.

  22. Return the result of converting result to an ECMAScript Object, as defined by [WebIDL].

Import Key
  1. Let keyData be the key data to be imported.

  2. If format is "spki":
    1. If usages contains an entry which is not "verify" then throw a SyntaxError.

    2. Let spki be the result of running the parse a subjectPublicKeyInfo algorithm over keyData.

    3. If an error occurred while parsing, then throw a DataError.

    4. Let hash be undefined.

    5. Let alg be the algorithm object identifier field of the algorithm AlgorithmIdentifier field of spki.

    6. If alg is equivalent to the rsaEncryption OID defined in RFC 3447:

      Let hash be undefined.

      If alg is equivalent to the id-RSASSA-PSS OID defined in RFC 3447:
      1. Let params be the ASN.1 structure contained within the parameters field of the algorithm AlgorithmIdentifier field of spki.

      2. If params is not defined, or is not an instance of the RSASSA-PSS-params ASN.1 type defined in RFC3447, throw a DataError.

      3. Let hashAlg be the AlgorithmIdentifier ASN.1 type within the hashAlgorithm field of params.

      4. If the algorithm object identifier field of hashAlg is equivalent to the id-sha1 OID defined in RFC 3447:

        Set hash to the string "SHA-1".

        If the algorithm object identifier field of hashAlg is equivalent to the id-sha256 OID defined in RFC 3447:

        Set hash to the string "SHA-256".

        If the algorithm object identifier field of hashAlg is equivalent to the id-sha384 OID defined in RFC 3447:

        Set hash to the string "SHA-384".

        If the algorithm object identifier field of hashAlg is equivalent to the id-sha512 OID defined in RFC 3447:

        Set hash to the string "SHA-512".

        Otherwise:
        1. Perform any key import steps defined by other applicable specifications, passing format, spki and obtaining hash.

        2. If an error occured or there are no applicable specifications, throw a DataError.

      5. If the algorithm object identifier field of the maskGenAlgorithm field of params is not equivalent to the OID id-mgf1 defined in RFC 3447, throw a NotSupportedError.

      6. If the parameters field of the maskGenAlgorithm field of params is not an instance of the HashAlgorithm ASN.1 type that is identical in content to the hashAlglorithm field of params, throw a NotSupportedError.

      Otherwise:

      throw a DataError.

    7. If hash is not undefined:
      1. Let normalizedHash be the result of normalize an algorithm with alg set to hash and op set to digest.

      2. If normalizedHash is not equal to the hash member of normalizedAlgorithm, throw a DataError.

    8. Let publicKey be the result of performing the parse an ASN.1 structure algorithm, with data as the subjectPublicKeyInfo field of spki, structure as the RSAPublicKey structure specified in Section A.1.1 of RFC 3447, and exactData set to true.

    9. If an error occurred while parsing, then throw a DataError.

    10. Let key be a new CryptoKey object that represents the RSA public key identified by publicKey.

    11. Set the [[type]] internal slot of key to "public"

    If format is "pkcs8":
    1. If usages contains an entry which is not "sign" then throw a SyntaxError.

    2. Let privateKeyInfo be the result of running the parse a privateKeyInfo algorithm over keyData.

    3. If an error occurred while parsing, then throw a DataError.

    4. Let hash be undefined.

    5. Let alg be the algorithm object identifier field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo.

    6. If alg is equivalent to the rsaEncryption OID defined in RFC 3447:

      Let hash be undefined.

      If alg is equivalent to the id-RSASSA-PSS OID defined in RFC 3447:
      1. Let params be the ASN.1 structure contained within the parameters field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo.

      2. If params is not defined, or is not an instance of the RSASSA-PSS-params ASN.1 type defined in RFC3447, throw a NotSupportedError.

      3. Let hashAlg be the AlgorithmIdentifier ASN.1 type within the hashAlgorithm field of params.

      4. If the algorithm object identifier field of hashAlg is equivalent to the id-sha1 OID defined in RFC 3447:

        Set hash to the string "SHA-1".

        If the algorithm object identifier field of hashAlg is equivalent to the id-sha256 OID defined in RFC 3447:

        Set hash to the string "SHA-256".

        If the algorithm object identifier field of hashAlg is equivalent to the id-sha384 OID defined in RFC 3447:

        Set hash to the string "SHA-384".

        If the algorithm object identifier field of hashAlg is equivalent to the id-sha512 OID defined in RFC 3447:

        Set hash to the string "SHA-512".

        Otherwise:
        1. Perform any key import steps defined by other applicable specifications, passing format, privateKeyInfo and obtaining hash.

        2. If an error occured or there are no applicable specifications, throw a DataError.

      5. If the algorithm object identifier field of the maskGenAlgorithm field of params is not equivalent to the OID id-mgf1 defined in RFC 3447, throw a NotSupportedError.

      6. If the parameters field of the maskGenAlgorithm field of params is not an instance of the HashAlgorithm ASN.1 type that is identical in content to the hashAlglorithm field of params, throw a NotSupportedError.

      Otherwise:

      throw a DataError.

    7. If hash is not undefined:
      1. Let normalizedHash be the result of normalize an algorithm with alg set to hash and op set to digest.

      2. If normalizedHash is not equal to the hash member of normalizedAlgorithm, throw a DataError.

    8. Let rsaPrivateKey be the result of performing the parse an ASN.1 structure algorithm, with data as the privateKey field of privateKeyInfo, structure as the RSAPrivateKey structure specified in Section A.1.2 of RFC 3447, and exactData set to true.

    9. If an error occurred while parsing, then throw a DataError.

    10. Let key be a new CryptoKey object that represents the RSA private key identified by rsaPrivateKey.

    11. Set the [[type]] internal slot of key to "private"

    If format is "jwk":
    1. Let jwk be the JsonWebKey dictionary represented by keyData.

    2. If the "d" field of jwk is present and usages contains an entry which is not "sign", or, if the "d" field of jwk is not present and usages contains an entry which is not "verify" then throw a SyntaxError.

    3. If the "kty" field of jwk is not a case-sensitive string match to "RSA", then throw a DataError.

    4. If the "use" field of jwk is present, and is not a case-sensitive string match to "sig", then throw a DataError.

    5. If the "key_ops" field of jwk is present, and is invalid according to the requirements of JSON Web Key or does not contain all of the specified usages values, then throw a DataError.

    6. If the "alg" field of jwk is not present:

      Let hash be undefined.

      If the "alg" field is equal to the string "PS1":

      Let hash be the string "SHA-1".

      If the "alg" field is equal to the string "PS256":

      Let hash be the string "SHA-256".

      If the "alg" field is equal to the string "PS384":

      Let hash be the string "SHA-384".

      If the "alg" field is equal to the string "PS512":

      Let hash be the string "SHA-512".

      Otherwise:
      1. Perform any key import steps defined by other applicable specifications, passing format, jwk and obtaining hash.

      2. If an error occured or there are no applicable specifications, throw a DataError.

    7. If hash is not undefined:
      1. Let normalizedHash be the result of normalize an algorithm with alg set to hash and op set to digest.

      2. If normalizedHash is not equal to the hash member of normalizedAlgorithm, throw a DataError.

    8. If the "d" field of jwk is present:
      1. If jwk does not meet the requirements of Section 6.3.2 of JSON Web Algorithms, then throw a DataError.

      2. Let key be a new CryptoKey object that represents the RSA private key identified by interpreting jwk according to Section 6.3.2 of JSON Web Algorithms.

      3. Set the [[type]] internal slot of key to "private"

      Otherwise:
      1. If jwk does not meet the requirements of Section 6.3.1 of JSON Web Algorithms, then throw a DataError.

      2. Let key be a new CryptoKey object that represents the RSA public key identified by interpreting jwk according to Section 6.3.1 of JSON Web Algorithms.

      3. Set the [[type]] internal slot of key to "public"

    Otherwise:
    throw a NotSupportedError.
  3. Let algorithm be a new RsaHashedKeyAlgorithm dictionary.

  4. Set the name attribute of algorithm to "RSA-PSS"

  5. Set the modulusLength attribute of algorithm to the length, in bits, of the RSA public modulus.

  6. Set the publicExponent attribute of algorithm to the BigInteger representation of the RSA public exponent.

  7. Set the hash attribute of algorithm to the hash member of normalizedAlgorithm.

  8. Set the [[algorithm]] internal slot of key to algorithm

  9. Return key.

Export Key
  1. Let key be the key to be exported.

  2. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  3. If format is "spki"
    1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

    2. Let data be an instance of the subjectPublicKeyInfo ASN.1 structure defined in RFC 5280 with the following properties:

      • Set the algorithm field to an AlgorithmIdentifier ASN.1 type with the following properties:

        • Set the algorithm field to the OID id-RSASSA-PSS defined in RFC 3447.

        • Set the params field to an instance of the RSASSA-PSS-params ASN.1 type with the following properties:

          • Set the hashAlgorithm field to an instance of the HashAlgorithm ASN.1 type with the following properties:

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-1":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha1 defined in RFC 3447.

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-256":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha256 defined in RFC 3447.

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-384":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha384 defined in RFC 3447.

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-512":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha512 defined in RFC 3447.

            Otherwise:
            1. Perform any key export steps defined by other applicable specifications, passing format and the hash attribute of the [[algorithm]] internal slot of key and obtaining hashOid and hashParams.

            2. Set the algorithm object identifier of hashAlgorithm to hashOid.

            3. Set the params field of hashAlgorithm to hashParams if hashParams is not undefined and omit the params field otherwise.

          • Set the maskGenAlgorithm field to an instance of the MaskGenAlgorithm ASN.1 type with the following properties:

            • Set the algorithm field to the OID id-mgf1 defined in RFC 3447.

            • Set the params field to an instance of the HashAlgorithm ASN.1 type that is identical to the hashAlgorithm field.

          • Set the saltLength field to the length in octets of the digest algorithm identified by the name attribute of the hash attribute of the [[algorithm]] internal slot of key.

      • Set the subjectPublicKey field to the result of DER-encoding an RSAPublicKey ASN.1 type, as defined in RFC 3447, Appendix A.1.1, that represents the RSA public key represented by the [[handle]] internal slot of key

    3. Let result be a new ArrayBuffer containing data.

    If format is "pkcs8":
    1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

    2. Let data be the result of encoding a privateKeyInfo structure with the following properties:

      • Set the version field to 0.

      • Set the privateKeyAlgorithm field to an PrivateKeyAlgorithmIdentifier ASN.1 type with the following properties:

        • Set the algorithm field to the OID id-RSASSA-PSS defined in RFC 3447.

        • Set the params field to an instance of the RSASSA-PSS-params ASN.1 type with the following properties:

          • Set the hashAlgorithm field to an instance of the HashAlgorithm ASN.1 type with the following properties:

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-1":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha1 defined in RFC 3447.

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-256":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha256 defined in RFC 3447.

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-384":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha384 defined in RFC 3447.

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-512":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha512 defined in RFC 3447.

            Otherwise:
            1. Perform any key export steps defined by other applicable specifications, passing format and the hash attribute of the [[algorithm]] internal slot of key and obtaining hashOid and hashParams.

            2. Set the algorithm object identifier of hashAlgorithm to hashOid.

            3. Set the params field of hashAlgorithm to hashParams if hashParams is not undefined and omit the params field otherwise.

          • Set the maskGenAlgorithm field to an instance of the MaskGenAlgorithm ASN.1 type with the following properties:

            • Set the algorithm field to the OID id-mgf1 defined in RFC 3447.

            • Set the params field to an instance of the HashAlgorithm ASN.1 type that is identical to the hashAlgorithm field.

          • Set the saltLength field to the length in octets of the digest algorithm identified by the name attribute of the hash attribute of the [[algorithm]] internal slot of key.

      • Set the privateKey field to the result of DER-encoding an RSAPrivateKey ASN.1 type, as defined in RFC 3447, Appendix A.1.2, that represents the RSA private key represented by the [[handle]] internal slot of key

        Editorial note
        RFC 5208 specifies that the encoding of this field should be BER encoded in Section 5 (as a "for example"). However, to avoid requiring WebCrypto implementations support BER-encoding and BER-decoding, only DER encodings are produced or accepted.
    3. Let result be a new ArrayBuffer containing data.

    If format is "jwk":
    • Let jwk be a new JsonWebKey dictionary.

    • Set the kty attribute of jwk to the string "RSA".

    • Let hash be the name attribute of the hash attribute of the [[algorithm]] internal slot of key.

    • If hash is "SHA-1":

      Set the alg attribute of jwk to the string "PS1".

      If hash is "SHA-256":

      Set the alg attribute of jwk to the string "PS256".

      If hash is "SHA-384":

      Set the alg attribute of jwk to the string "PS384".

      If hash is "SHA-512":

      Set the alg attribute of jwk to the string "PS512".

      Otherwise:
      1. Perform any key export steps defined by other applicable specifications, passing format and the hash attribute of the [[algorithm]] internal slot of key and obtaining alg.

      2. Set the alg attribute of jwk to alg.

    • Set the attributes n and e of jwk according to the corresponding definitions in JSON Web Algorithms, Section 6.3.1.

    • If the [[type]] internal slot of key is "private":
      1. Set the attributes named d, p, q, dp, dq, and qi of jwk according to the corresponding definitions in JSON Web Algorithms, Section 6.3.2.

      2. If the underlying RSA private key represented by the [[handle]] internal slot of key is represented by more than two primes, set the attribute named oth of jwk according to the corresponding definition in JSON Web Algorithms, Section 6.3.2.7

    • Set the key_ops attribute of jwk to the usages attribute of key.

    • Set the ext attribute of jwk to the [[extractable]] internal slot of key.

    • Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise

    throw a NotSupportedError.

  4. Return result.

22. RSA-OAEP

22.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 SHA hash functions defined in this specification and using the mask generation function MGF1.

Other specifications may specify the use of additional hash algorithms with RSAES-OAEP. Such specifications must define the digest operation for the additional hash algorithm and key import steps and key export steps for RSAES-OAEP.

22.2. Registration

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

Operation Parameters Result
encrypt RsaOaepParams ArrayBuffer
decrypt RsaOaepParams ArrayBuffer
generateKey RsaHashedKeyGenParams CryptoKeyPair
importKey RsaHashedImportParams CryptoKey
exportKey None object

22.3. RsaOaepParams dictionary

IDL

dictionary RsaOaepParams : Algorithm {
// The optional label/application data to associate with the message
BufferSource label;
};
          

22.4. Operations

Encrypt
  1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

  2. Let label be the contents of the label member of normalizedAlgorithm or the empty octet string if the label member of normalizedAlgorithm is not present.

  3. Perform the encryption operation defined in Section 7.1 of [RFC3447] with the key represented by key as the recipient's RSA public key, the contents of plaintext as the message to be encrypted, M and label as the label, L, and with the hash function specified by the hash attribute of the [[algorithm]] internal slot of key as the Hash option and MGF1 (defined in Section B.2.1 of [RFC3447]) as the MGF option.

  4. If performing the operation results in an error, then throw an OperationError.

  5. Let ciphertext be a new ArrayBuffer containing the value C that results from performing the operation.

Decrypt
  1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

  2. Let label be the contents of the label member of normalizedAlgorithm or the empty octet string if the label member of normalizedAlgorithm is not present.

  3. Perform the decryption operation defined in Section 7.1 of [RFC3447] with the key represented by key as the recipient's RSA private key, the contents of ciphertext as the ciphertext to be decrypted, C, and label as the label, L, and with the hash function specified by the hash attribute of the [[algorithm]] internal slot of key as the Hash option and MGF1 (defined in Section B.2.1 of [RFC3447]) as the MGF option.

  4. If performing the operation results in an error, then throw an OperationError.

  5. Let plaintext be a new ArrayBuffer containing the value M that results from performing the operation.

Generate Key
  1. If usages contains an entry which is not "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. Generate an RSA key pair, as defined in [RFC3447], with RSA modulus length equal to the modulusLength member of normalizedAlgorithm and RSA public exponent equal to the publicExponent member of normalizedAlgorithm.

  3. If performing the operation results in an error, then throw an OperationError.

  4. Let algorithm be a new RsaHashedKeyAlgorithm object.

  5. Set the name attribute of algorithm to "RSA-OAEP".

  6. Set the modulusLength attribute of algorithm to equal the modulusLength member of normalizedAlgorithm.

  7. Set the publicExponent attribute of algorithm to equal the publicExponent member of normalizedAlgorithm.

  8. Set the hash attribute of algorithm to equal the hash member of normalizedAlgorithm.

  9. Let publicKey be a new CryptoKey object representing the public key of the generated key pair.

  10. Set the [[type]] internal slot of publicKey to "public"

  11. Set the [[algorithm]] internal slot of publicKey to algorithm.

  12. Set the [[extractable]] internal slot of publicKey to true.

  13. Set the [[usages]] internal slot of publicKey to be the usage intersection of usages and [ "encrypt", "wrapKey" ].

  14. Let privateKey be a new CryptoKey object representing the private key of the generated key pair.

  15. Set the [[type]] internal slot of privateKey to "private"

  16. Set the [[algorithm]] internal slot of privateKey to algorithm.

  17. Set the [[extractable]] internal slot of privateKey to extractable.

  18. Set the [[usages]] internal slot of privateKey to be the usage intersection of usages and [ "decrypt", "unwrapKey" ].

  19. Let result be a new CryptoKeyPair dictionary.

  20. Set the publicKey attribute of result to be publicKey.

  21. Set the privateKey attribute of result to be privateKey.

  22. Return the result of converting result to an ECMAScript Object, as defined by [WebIDL].

Import Key
  1. Let keyData be the key data to be imported.

  2. If format is "spki":
    1. If usages contains an entry which is not "encrypt" or "wrapKey", then throw a SyntaxError.

    2. Let spki be the result of running the parse a subjectPublicKeyInfo algorithm over keyData.

    3. If an error occurred while parsing, then throw a DataError.

    4. Let hash be a string whose initial value is undefined.

    5. Let alg be the algorithm object identifier field of the algorithm AlgorithmIdentifier field of spki.

    6. If alg is equivalent to the rsaEncryption OID defined in RFC 3447:

      Let hash be undefined.

      If alg is equivalent to the id-RSAES-OAEP OID defined in RFC 3447:
      1. Let params be the ASN.1 structure contained within the parameters field of the algorithm AlgorithmIdentifier field of spki.

      2. If params is not defined, or is not an instance of the RSAES-OAEP-params ASN.1 type defined in RFC3447, throw a DataError.

      3. Let hashAlg be the AlgorithmIdentifier ASN.1 type within the hashAlgorithm field of params.

      4. If the algorithm object identifier field of hashAlg is equivalent to the id-sha1 OID defined in RFC 3447:

        Set hash to the string "SHA-1".

        If the algorithm object identifier field of hashAlg is equivalent to the id-sha256 OID defined in RFC 3447:

        Set hash to the string "SHA-256".

        If the algorithm object identifier field of hashAlg is equivalent to the id-sha384 OID defined in RFC 3447:

        Set hash to the string "SHA-384".

        If the algorithm object identifier field of hashAlg is equivalent to the id-sha512 OID defined in RFC 3447:

        Set hash to the string "SHA-512".

        Otherwise:
        1. Perform any key import steps defined by other applicable specifications, passing format, spki and obtaining hash.

        2. If an error occured or there are no applicable specifications, throw a DataError.

      5. If the algorithm object identifier field of the maskGenAlgorithm field of params is not equivalent to the OID id-mgf1 defined in RFC 3447, throw a NotSupportedError.

      6. If the parameters field of the maskGenAlgorithm field of params is not an instance of the HashAlgorithm ASN.1 type that is identical in content to the hashAlglorithm field of params, throw a NotSupportedError.

      Otherwise:

      throw a DataError.

    7. If hash is not undefined:
      1. Let normalizedHash be the result of normalize an algorithm with alg set to hash and op set to digest.

      2. If normalizedHash is not equal to the hash member of normalizedAlgorithm, throw a DataError.

    8. Let publicKey be the result of performing the parse an ASN.1 structure algorithm, with data as the subjectPublicKeyInfo field of spki, structure as the RSAPublicKey structure specified in Section A.1.1 of RFC 3447, and exactData set to true.

    9. If an error occurred while parsing, then throw a DataError.

    10. Let key be a new CryptoKey object that represents the RSA public key identified by publicKey.

    11. Set the [[type]] internal slot of key to "public"

    If format is "pkcs8":
    1. If usages contains an entry which is not "decrypt" or "unwrapKey", then throw a SyntaxError.

    2. Let privateKeyInfo be the result of running the parse a privateKeyInfo algorithm over keyData.

    3. If an error occurred while parsing, then throw a DataError.

    4. Let hash be a string whose initial value is undefined.

    5. Let alg be the algorithm object identifier field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo.

    6. If alg is equivalent to the rsaEncryption OID defined in RFC 3447:

      Let hash be undefined.

      If alg is equivalent to the id-RSAES-OAEP OID defined in RFC 3447:
      1. Let params be the ASN.1 structure contained within the parameters field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo.

      2. If params is not defined, or is not an instance of the RSAES-OAEP-params ASN.1 type defined in RFC3447, throw a NotSupportedError.

      3. Let hashAlg be the AlgorithmIdentifier ASN.1 type within the hashAlgorithm field of params.

      4. If the algorithm object identifier field of hashAlg is equivalent to the id-sha1 OID defined in RFC 3447:

        Set hash to the string "SHA-1".

        If the algorithm object identifier field of hashAlg is equivalent to the id-sha256 OID defined in RFC 3447:

        Set hash to the string "SHA-256".

        If the algorithm object identifier field of hashAlg is equivalent to the id-sha384 OID defined in RFC 3447:

        Set hash to the string "SHA-384".

        If the algorithm object identifier field of hashAlg is equivalent to the id-sha512 OID defined in RFC 3447:

        Set hash to the string "SHA-512".

        Otherwise:
        1. Perform any key import steps defined by other applicable specifications, passing format, spki and obtaining hash.

        2. If an error occured or there are no applicable specifications, throw a DataError.

      5. If the algorithm object identifier field of the maskGenAlgorithm field of params is not equivalent to the OID id-mgf1 defined in RFC 3447, throw a NotSupportedError.

      6. If the parameters field of the maskGenAlgorithm field of params is not an instance of the HashAlgorithm ASN.1 type that is identical in content to the hashAlglorithm field of params, throw a NotSupportedError.

      Otherwise:

      throw a DataError.

    7. If hash is not undefined:
      1. Let normalizedHash be the result of normalize an algorithm with alg set to hash and op set to digest.

      2. If normalizedHash is not equal to the hash member of normalizedAlgorithm, throw a DataError.

    8. Let rsaPrivateKey be the result of performing the parse an ASN.1 structure algorithm, with data as the privateKey field of privateKeyInfo, structure as the RSAPrivateKey structure specified in Section A.1.2 of RFC 3447, and exactData set to true.

    9. If an error occurred while parsing, then throw a DataError.

    10. Let key be a new CryptoKey object that represents the RSA private key identified by rsaPrivateKey.

    11. Set the [[type]] internal slot of key to "private"

    If format is "jwk":
    1. Let jwk be the JsonWebKey dictionary represented by keyData.

    2. If the "d" field of jwk is present and usages contains an entry which is not "decrypt" or "unwrapKey", then throw a SyntaxError.

    3. If the "d" field of jwk is not present and usages contains an entry which is not "encrypt" or "wrapKey", then throw a SyntaxError.

    4. If the "kty" field of jwk is not a case-sensitive string match to "RSA", then throw a DataError.

    5. If the "use" field of jwk is present, and is not a case-sensitive string match to "enc", then throw a DataError.

    6. If the "key_ops" field of jwk is present, and is invalid according to the requirements of JSON Web Key or does not contain all of the specified usages values, then throw a DataError.

    7. If the alg field of jwk is not present:
      Let hash be undefined.
      If the alg field of jwk is equal to "RSA-OAEP":
      Let hash be the string "SHA-1".
      If the alg field of jwk is equal to "RSA-OAEP-256":
      Let hash be the string "SHA-256".
      If the alg field of jwk is equal to "RSA-OAEP-384":
      Let hash be the string "SHA-384".
      If the alg field of jwk is equal to "RSA-OAEP-512":
      Let hash be the string "SHA-512".
      Otherwise:
      1. Perform any key import steps defined by other applicable specifications, passing format, jwk and obtaining hash.

      2. If an error occured or there are no applicable specifications, throw a DataError.

    8. If hash is not undefined:
      1. Let normalizedHash be the result of normalize an algorithm with alg set to hash and op set to digest.

      2. If normalizedHash is not equal to the hash member of normalizedAlgorithm, throw a DataError.

    9. If the "d" field of jwk is present:
      1. If jwk does not meet the requirements of Section 6.3.2 of JSON Web Algorithms, then throw a DataError.

      2. Let key be a new CryptoKey object that represents the RSA private key identified by interpreting jwk according to Section 6.3.2 of JSON Web Algorithms.

      3. Set the [[type]] internal slot of key to "private"

      Otherwise:
      1. If jwk does not meet the requirements of Section 6.3.1 of JSON Web Algorithms, then throw a DataError.

      2. Let key be a new CryptoKey object that represents the RSA public key identified by interpreting jwk according to Section 6.3.1 of JSON Web Algorithms.

      3. Set the [[type]] internal slot of key to "public"

    Otherwise:
    throw a NotSupportedError.
  3. Let algorithm be a new RsaHashedKeyAlgorithm.

  4. Set the name attribute of algorithm to "RSA-OAEP"

  5. Set the modulusLength attribute of algorithm to the length, in bits, of the RSA public modulus.

  6. Set the publicExponent attribute of algorithm to the BigInteger representation of the RSA public exponent.

  7. Set the hash attribute of algorithm to the hash member of normalizedAlgorithm.

  8. Set the [[algorithm]] internal slot of key to algorithm

  9. Return key.

Export Key
  1. Let key be the key to be exported.

  2. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw a OperationError.

  3. If format is "spki"
    1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

    2. Let data be an instance of the subjectPublicKeyInfo ASN.1 structure defined in RFC 5280 with the following properties:

      • Set the algorithm field to an AlgorithmIdentifier ASN.1 type with the following properties:

        • Set the algorithm field to the OID id-RSAES-OAEP defined in RFC 3447.

        • Set the params field to an instance of the RSAES-OAEP-params ASN.1 type with the following properties:

          • Set the hashAlgorithm field to an instance of the HashAlgorithm ASN.1 type with the following properties:

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-1":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha1 defined in RFC 3447.

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-256":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha256 defined in RFC 3447.

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-384":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha384 defined in RFC 3447.

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-512":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha512 defined in RFC 3447.

            Otherwise:
            1. Perform any key export steps defined by other applicable specifications, passing format and the hash attribute of the [[algorithm]] internal slot of key and obtaining hashOid and hashParams.

            2. Set the algorithm object identifier of hashAlgorithm to hashOid.

            3. Set the params field of hashAlgorithm to hashParams if hashParams is not undefined and omit the params field otherwise.

          • Set the maskGenAlgorithm field to an instance of the MaskGenAlgorithm ASN.1 type with the following properties:

            • Set the algorithm field to the OID id-mgf1 defined in RFC 3447.

            • Set the params field to an instance of the HashAlgorithm ASN.1 type that is identical to the hashAlgorithm field.

      • Set the subjectPublicKey field to the result of DER-encoding an RSAPublicKey ASN.1 type, as defined in RFC 3447, Appendix A.1.1, that represents the RSA public key represented by the [[handle]] internal slot of key

    3. Let result be a new ArrayBuffer containing data.

    If format is "pkcs8":
    1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

    2. Let data be the result of encoding a privateKeyInfo structure with the following properties:

      • Set the version field to 0.

      • Set the privateKeyAlgorithm field to an PrivateKeyAlgorithmIdentifier ASN.1 type with the following properties:

        • Set the algorithm field to the OID id-RSAES-OAEP defined in RFC 3447.

        • Set the params field to an instance of the RSAES-OAEP-params ASN.1 type with the following properties:

          • Set the hashAlgorithm field to an instance of the HashAlgorithm ASN.1 type with the following properties:

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-1":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha1 defined in RFC 3447.

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-256":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha256 defined in RFC 3447.

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-384":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha384 defined in RFC 3447.

            If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-512":

            Set the algorithm object identifier of hashAlgorithm to the OID id-sha512 defined in RFC 3447.

            Otherwise:
            1. Perform any key export steps defined by other applicable specifications, passing format and the hash attribute of the [[algorithm]] internal slot of key and obtaining hashOid and hashParams.

            2. Set the algorithm object identifier of hashAlgorithm to hashOid.

            3. Set the params field of hashAlgorithm to hashParams if hashParams is not undefined and omit the params field otherwise.

          • Set the maskGenAlgorithm field to an instance of the MaskGenAlgorithm ASN.1 type with the following properties:

            • Set the algorithm field to the OID id-mgf1 defined in RFC 3447.

            • Set the params field to an instance of the HashAlgorithm ASN.1 type that is identical to the hashAlgorithm field.

      • Set the privateKey field to the result of DER-encoding an RSAPrivateKey ASN.1 type, as defined in RFC 3447, Appendix A.1.2, that represents the RSA private key represented by the [[handle]] internal slot of key

        Editorial note
        RFC 5208 specifies that the encoding of this field should be BER encoded in Section 5 (as a "for example"). However, to avoid requiring WebCrypto implementations support BER-encoding and BER-decoding, only DER encodings are produced or accepted.
    3. Let result be a new ArrayBuffer containing data.

    If format is "jwk":
    • Let jwk be a new JsonWebKey dictionary.

    • Set the kty attribute of jwk to the string "RSA".

    • If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-1":

      Set the alg attribute of jwk to the string "RSA-OAEP".

      If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-256":

      Set the alg attribute of jwk to the string "RSA-OAEP-256".

      If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-384":

      Set the alg attribute of jwk to the string "RSA-OAEP-384".

      If the name attribute of the hash attribute of the [[algorithm]] internal slot of key is "SHA-512":

      Set the alg attribute of jwk to the string "RSA-OAEP-512".

      Otherwise:
      1. Perform any key export steps defined by other applicable specifications, passing format and the hash attribute of the [[algorithm]] internal slot of key and obtaining alg.

      2. Set the alg attribute of jwk to alg.

    • Set the attributes n and e of jwk according to the corresponding definitions in JSON Web Algorithms, Section 6.3.1.

    • If the [[type]] internal slot of key is "private":
      1. Set the attributes named d, p, q, dp, dq, and qi of jwk according to the corresponding definitions in JSON Web Algorithms, Section 6.3.2.

      2. If the underlying RSA private key represented by the [[handle]] internal slot of key is represented by more than two primes, set the attribute named oth of jwk according to the corresponding definition in JSON Web Algorithms, Section 6.3.2.7

    • Set the key_ops attribute of jwk to the usages attribute of key.

    • Set the ext attribute of jwk to the [[extractable]] internal slot of key.

    • Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise

    throw a NotSupportedError.

  4. Return result.

23. ECDSA

23.1. Description

The "ECDSA" algorithm identifier is used to perform signing and verification using the ECDSA algorithm specified in [X9.62] and using the SHA hash functions and elliptic curves defined in this specification.

Other specifications may specify the use of additional elliptic curves and hash algorithms with ECDSA. To specify additional hash algorithms to be used with ECDSA, a specification must define a registered algorithm that supports the digest operation. To specify an additional elliptic curve a specification must define the curve name, ECDSA signature steps, ECDSA verification steps, ECDSA generation steps, ECDSA key import steps and ECDSA key export steps.

23.2. Registration

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

Operation Parameters Result
sign EcdsaParams ArrayBuffer
verify EcdsaParams boolean
generateKey EcKeyGenParams CryptoKeyPair
importKey EcKeyImportParams CryptoKey
exportKey None object

23.3. EcdsaParams dictionary

IDL

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

23.4. EcKeyGenParams dictionary

IDL

typedef DOMString NamedCurve;

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

The NamedCurve type represents named elliptic curves, which are a convenient way to specify the domain parameters of well-known elliptic curves. The following values defined by this specification:

"P-256"
NIST recommended curve P-256, also known as secp256r1.
"P-384"
NIST recommended curve P-384, also known as secp384r1.
"P-521"
NIST recommended curve P-521, also known as secp521r1.

Other specifications may define additional values.

23.5. EcKeyAlgorithm dictionary

IDL

dictionary EcKeyAlgorithm : KeyAlgorithm {
// The named curve that the key uses
required NamedCurve namedCurve;
};
          

23.6. EcKeyImportParams dictionary

IDL

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

23.7. Operations

Sign
When signing, the following algorithm should be used:
  1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

  2. Let hashAlgorithm be the hash member of normalizedAlgorithm.

  3. If hashAlgorithm does not describe a registered algorithm that supports the digest operation, then throw a NotSupportedError.

  4. Let M be the result of performing the digest operation specified by hashAlgorithm using message.

  5. Let d be the ECDSA private key associated with key.

  6. Let params be the EC domain parameters associated with key.

  7. If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256", "P-384" or "P-521":
    1. 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.

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

    3. Let result be a new ArrayBuffer.

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

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

    Otherwise, the namedCurve attribute of the [[algorithm]] internal slot of key is a value specified in an applicable specification:

    Perform the ECDSA signature steps specified in that specification, passing in M, params and d and resulting in result.

  8. Return result.

Verify
When verifying, the following algorithm should be used:
  1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

  2. Let hashAlgorithm be the hash member of normalizedAlgorithm.

  3. If hashAlgorithm does not describe a registered algorithm that supports the digest operation, then throw a NotSupportedError.

  4. Let M be the result of performing the digest operation specified by hashAlgorithm using message.

  5. Let Q be the ECDSA public key associated with key.

  6. Let params be the EC domain parameters associated with key.

  7. If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256", "P-384" or "P-521":

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

    Otherwise, the namedCurve attribute of the [[algorithm]] internal slot of key is a value specified in an applicable specification:

    Perform the ECDSA verification steps specified in that specification passing in M, signature, params and Q and resulting in an indication of whether or not the purported signature is valid.

  8. 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.

  9. Return result.

Generate Key
  1. If usages contains a value which is not one of "sign" or "verify", then throw a SyntaxError.

  2. If the namedCurve member of normalizedAlgorithm is "P-256", "P-384" or "P-521":

    Generate an Elliptic Curve key pair, as defined in [X9.62] with domain parameters for the curve identified by the namedCurve member of normalizedAlgorithm.

    If the namedCurve member of normalizedAlgorithm is a value specified in an applicable specification:

    Perform the ECDSA key generation steps specified in that specification, passing in normalizedAlgorithm and resulting in an elliptic curve key pair.

    Otherwise:

    throw a NotSupportedError

  3. If performing the key generation operation results in an error, then throw an OperationError.

  4. Let algorithm be a new EcKeyAlgorithm object.

  5. Set the name attribute of algorithm to "ECDSA".

  6. Set the namedCurve attribute of algorithm to equal the namedCurve member of normalizedAlgorithm.

  7. Let publicKey be a new CryptoKey object representing the public key of the generated key pair.

  8. Set the [[type]] internal slot of publicKey to "public"

  9. Set the [[algorithm]] internal slot of publicKey to algorithm.

  10. Set the [[extractable]] internal slot of publicKey to true.

  11. Set the [[usages]] internal slot of publicKey to be the usage intersection of usages and [ "verify" ].

  12. Let privateKey be a new CryptoKey object representing the private key of the generated key pair.

  13. Set the [[type]] internal slot of privateKey to "private"

  14. Set the [[algorithm]] internal slot of privateKey to algorithm.

  15. Set the [[extractable]] internal slot of privateKey to extractable.

  16. Set the [[usages]] internal slot of privateKey to be the usage intersection of usages and [ "sign" ].

  17. Let result be a new CryptoKeyPair dictionary.

  18. Set the publicKey attribute of result to be publicKey.

  19. Set the privateKey attribute of result to be privateKey.

  20. Return the result of converting result to an ECMAScript Object, as defined by [WebIDL].

Import Key
  1. Let keyData be the key data to be imported.

  2. If format is "spki":
    1. If usages contains a value which is not "verify" then throw a SyntaxError.

    2. Let spki be the result of running the parse a subjectPublicKeyInfo algorithm over keyData

    3. If an error occurred while parsing, then throw a DataError.

    4. If the algorithm object identifier field of the algorithm AlgorithmIdentifier field of spki is not equal to the id-ecPublicKey object identifier defined in RFC 5480, then throw a DataError.

    5. If the parameters field of the algorithm AlgorithmIdentifier field of spki is absent, then throw a DataError.

    6. Let params be the parameters field of the algorithm AlgorithmIdentifier field of spki.

    7. If params is not an instance of the ECParameters ASN.1 type defined in RFC 5480 that specifies a namedCurve, then throw a DataError.

    8. Let namedCurve be a string whose initial value is undefined.

    9. If params is equivalent to the secp256r1 object identifier defined in RFC 5480:

      Set namedCurve "P-256".

      If params is equivalent to the secp384r1 object identifier defined in RFC 5480:

      Set namedCurve "P-384".

      If params is equivalent to the secp521r1 object identifier defined in RFC 5480:

      Set namedCurve "P-521".

    10. If namedCurve is not undefined:

      Let key be a new CryptoKey object that represents the Elliptic Curve public key identified by performing the conversion steps defined in Section 2.2 of RFC 5480.

      Otherwise:
      1. Perform any key import steps defined by other applicable specifications, passing format, spki and obtaining namedCurve and key.

      2. If an error occured or there are no applicable specifications, throw a DataError.

    11. If namedCurve is defined, and not equal to the namedCurve member of normalizedAlgorithm, throw a DataError.

    12. If the public key value is not a valid point on the Elliptic Curve identified by the namedCurve member of normalizedAlgorithm throw a DataError.

    13. Set the [[type]] internal slot of key to "public"

    14. Let algorithm be a new EcKeyAlgorithm.

    15. Set the name attribute of algorithm to "ECDSA".

    16. Set the namedCurve attribute of algorithm to namedCurve.

    17. Set the [[algorithm]] internal slot of key to algorithm.

    If format is "pkcs8":
    1. If usages contains a value which is not "sign" then throw a SyntaxError.

    2. Let privateKeyInfo be the result of running the parse a privateKeyInfo algorithm over keyData.

    3. If an error occurs while parsing, then throw a DataError.

    4. If the algorithm object identifier field of the privateKeyAlgorithm PrivateKeyAlgorithm field of privateKeyInfo is not equal to the id-ecPublicKey object identifier defined in RFC 5480, then throw a DataError.

    5. If the parameters field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo is not present, then throw a DataError.

    6. Let params be the parameters field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo.

    7. If params is not an instance of the ECParameters ASN.1 type defined in RFC 5480 that specifies a namedCurve, then throw a DataError.

    8. Let namedCurve be a string whose initial value is undefined.

    9. If params is equivalent to the secp256r1 object identifier defined in RFC 5480:

      Set namedCurve "P-256".

      If params is equivalent to the secp384r1 object identifier defined in RFC 5480:

      Set namedCurve "P-384".

      If params is equivalent to the secp521r1 object identifier defined in RFC 5480:

      Set namedCurve "P-521".

    10. If namedCurve is not undefined:
      1. Let ecPrivateKey be the result of performing the parse an ASN.1 structure algorithm, with data as the privateKey field of privateKeyInfo, structure as the ASN.1 ECPrivateKey structure specified in Section 3 of RFC 5915, and exactData set to true.

      2. If an error occurred while parsing, then throw a DataError.

      3. If the parameters field of ecPrivateKey is present, and is not an instance of the namedCurve ASN.1 type defined in RFC 5480, or does not contain the same object identifier as the parameters field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo, then throw a DataError.

      4. Let key be a new CryptoKey object that represents the Elliptic Curve private key identified by performing the conversion steps defined in Section 3 of RFC 5915 using ecPrivateKey.

      Otherwise:
      1. Perform any key import steps defined by other applicable specifications, passing format, privateKeyInfo and obtaining namedCurve and key.

      2. If an error occured or there are no applicable specifications, throw a DataError.

    11. If namedCurve is defined, and not equal to the namedCurve member of normalizedAlgorithm, throw a DataError.

    12. If the private key value is not a valid point on the Elliptic Curve identified by the namedCurve member of normalizedAlgorithm throw a DataError.

    13. Set the [[type]] internal slot of key to "private"

    14. Let algorithm be a new EcKeyAlgorithm.

    15. Set the name attribute of algorithm to "ECDSA".

    16. Set the namedCurve attribute of algorithm to namedCurve.

    17. Set the [[algorithm]] internal slot of key to algorithm.

    If format is "jwk":
    1. Let jwk be the JsonWebKey dictionary represented by keyData.

    2. If an error occurred while parsing, then throw a DataError.

    3. If the "d" field is present and usages contains a value which is not "sign", or, if the "d" field is not present and usages contains a value which is not "verify" then throw a SyntaxError.

    4. If the "kty" field of jwk is not "EC", then throw a DataError.

    5. If the "use" field of jwk is present, and is not "sig", then throw a DataError.

    6. If the "key_ops" field of jwk is present, and is invalid according to the requirements of JSON Web Key, or it does not contain all of the specified usages values, then throw a DataError.

    7. If the "ext" field of jwk is present and has the value false and extractable is true, then throw a DataError.

    8. Let namedCurve be a string whose value is equal to the "crv" field of jwk.

    9. If namedCurve is not equal to the namedCurve member of normalizedAlgorithm, throw a DataError.

    10. If namedCurve is equal to "P-256", "P-384" or "P-521":
      1. Let algNamedCurve be a string whose initial value is undefined.

      2. If the "alg" field is not present:
        Let algNamedCurve be undefined.
        If the "alg" field is equal to the string "ES256":
        Let algNamedCurve be the string "P-256".
        If the "alg" field is equal to the string "ES384":
        Let algNamedCurve be the string "P-384".
        If the "alg" field is equal to the string "ES521":
        Let algNamedCurve be the string "P-521".
        otherwise:
        throw a DataError.
      3. If algNamedCurve is defined, and is not equal to namedCurve, throw a DataError.

      4. If the "d" field is present:
        1. If jwk does not meet the requirements of Section 6.2.2 of JSON Web Algorithms, then throw a DataError.

        2. Let key be a new CryptoKey object that represents the Elliptic Curve private key identified by interpreting jwk according to Section 6.2.2 of JSON Web Algorithms.

        3. Set the [[type]] internal slot of Key to "private".

        Otherwise:
        1. If jwk does not meet the requirements of Section 6.2.1 of JSON Web Algorithms, then throw a DataError.

        2. Let key be a new CryptoKey object that represents the Elliptic Curve public key identified by interpreting jwk according to Section 6.2.1 of JSON Web Algorithms.

        3. Set the [[type]] internal slot of Key to "public".

      Otherwise:
      1. Perform any key import steps defined by other applicable specifications, passing format, jwk and obtaining key.

      2. If an error occured or there are no applicable specifications, throw a DataError.

    11. If the key value is not a valid point on the Elliptic Curve identified by the namedCurve member of normalizedAlgorithm throw a DataError.

    12. Let algorithm be a new instance of an EcKeyAlgorithm object.

    13. Set the name attribute of algorithm to "ECDSA".

    14. Set the namedCurve attribute of algorithm to namedCurve.

    15. Set the [[algorithm]] internal slot of key to algorithm.

    Otherwise:

    throw a NotSupportedError.

  3. Return key

Export Key
  1. Let key be the CryptoKey to be exported.

  2. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  3. If format is "spki":
    1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

    2. Let data be an instance of the subjectPublicKeyInfo ASN.1 structure defined in RFC 5280 with the following properties:

      • Set the algorithm field to an AlgorithmIdentifier ASN.1 type with the following properties:

        • Set the algorithm object identifier to the OID 1.2.840.10045.2.1.

        • Set the parameters field to an instance of the ECParameters ASN.1 type defined in RFC 5480 as follows:

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256", "P-384" or "P-521":

          Let keyData be the octet string that represents the Elliptic Curve public key represented by the [[handle]] internal slot of key according to the encoding rules specified in Section 2.2 of RFC 5480 and using the uncompressed form. and keyData.

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256":

          Set parameters to the namedCurve choice with value equal to the object identifier secp256r1 defined in RFC 5480

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-384":

          Set parameters to the namedCurve choice with value equal to the object identifier secp384r1 defined in RFC 5480

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-521":

          Set parameters to the namedCurve choice with value equal to the object identifier secp521r1 defined in RFC 5480

          Otherwise:
          1. Perform any key export steps defined by other applicable specifications, passing format and the namedCurve attribute of the [[algorithm]] internal slot of key and obtaining namedCurveOid and keyData.

          2. Set parameters to the namedCurve choice with value equal to the object identifier namedCurveOid.

      • Set the subjectPublicKey field to keyData.

    3. Let result be a new ArrayBuffer containing data.

    If format is "pkcs8":
    1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

    2. Let data be an instance of the privateKeyInfo ASN.1 structure defined in RFC 5280 with the following properties:

      • Set the version field to 0.

      • Set the privateKeyAlgorithm field to an PrivateKeyAlgorithmIdentifier ASN.1 type with the following properties:

        • Set the algorithm object identifier to the OID 1.2.840.10045.2.1.

        • Set the parameters field to an instance of the ECParameters ASN.1 type defined in RFC 5480 as follows:

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256", "P-384" or "P-521":

          Let keyData be the result of DER-encoding an instance of the ECPrivateKey structure defined in Section 3 of RFC 5915 for the Elliptic Curve private key represented by the [[handle]] internal slot of key and that conforms to the following:

          • The parameters field is present, and is equivalent to the parameters field of the privateKeyAlgorithm field of this PrivateKeyInfo ASN.1 structure.

          • The publicKey field is present and represents the Elliptic Curve public key associated with the Elliptic Curve private key represented by the [[handle]] internal slot of key.

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256":

          Set parameters to the namedCurve choice with value equal to the object identifier secp256r1 defined in RFC 5480

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-384":

          Set parameters to the namedCurve choice with value equal to the object identifier secp384r1 defined in RFC 5480

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-521":

          Set parameters to the namedCurve choice with value equal to the object identifier secp521r1 defined in RFC 5480

          Otherwise:
          1. Perform any key export steps defined by other applicable specifications, passing format and the namedCurve attribute of the [[algorithm]] internal slot of key and obtaining namedCurveOid and keyData.

          2. Set parameters to the namedCurve choice with value equal to the object identifier namedCurveOid.

      • Set the privateKey field to keyData.

    3. Let result be a new ArrayBuffer containing data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to "EC".

    3. If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256", "P-384" or "P-521":
      1. If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256":
        Set the crv attribute of jwk to "P-256"
        If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-384":
        Set the crv attribute of jwk to "P-384"
        If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-521":
        Set the crv attribute of jwk to "P-521"
      2. Set the x attribute of jwk according to the definition in Section 6.2.1.2 of JSON Web Algorithms.

      3. Set the y attribute of jwk according to the definition in Section 6.2.1.3 of JSON Web Algorithms.

      4. If the [[type]] internal slot of key is "private"

        Set the d attribute of jwk according to the definition in Section 6.2.2.1 of JSON Web Algorithms.

      Otherwise:
      1. Perform any key export steps defined by other applicable specifications, passing format and the namedCurve attribute of the [[algorithm]] internal slot of key and obtaining namedCurve and a new value of jwk.

      2. Set the crv attribute of jwk to namedCurve.

    4. Set the key_ops attribute of jwk to the usages attribute of key.

    5. Set the ext attribute of jwk to the [[extractable]] internal slot of key.

    6. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  4. Return result.

24. ECDH

24.1. Description

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

Other specifications may specify the use of additional elliptic curves with ECDH. To specify an additional elliptic curve a specification must define the curve name, ECDH generation steps, ECDH derivation steps, ECDH key import steps and ECDH key export steps.

24.2. Registration

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

Operation Parameters Result
generateKey EcKeyGenParams CryptoKeyPair
deriveBits EcdhKeyDeriveParams Octet string
importKey EcKeyImportParams CryptoKey
exportKey None object

24.3. EcdhKeyDeriveParams dictionary

IDL

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

24.4. Operations

Generate Key
  1. If usages contains an entry which is not "deriveKey" or "deriveBits" then throw a SyntaxError.

  2. If the namedCurve member of normalizedAlgorithm is "P-256", "P-384" or "P-521":

    Generate an Elliptic Curve key pair, as defined in [X9.63] with domain parameters for the curve identified by the namedCurve member of normalizedAlgorithm.

    If the namedCurve member of normalizedAlgorithm is a value specified in an applicable specification that specifies the use of that value with ECDH:

    Perform the ECDH key generation steps specified in that specification, passing in normalizedAlgorithm and resulting in an elliptic curve key pair.

    Otherwise:

    throw a NotSupportedError

  3. If performing the operation results in an error, then throw a OperationError.

  4. Let algorithm be a new EcKeyAlgorithm object.

  5. Set the name member of algorithm to "ECDH".

  6. Set the namedCurve attribute of algorithm to equal the namedCurve member of normalizedAlgorithm.

  7. Let publicKey be a new CryptoKey object representing the public key of the generated key pair.

  8. Set the [[type]] internal slot of publicKey to "public"

  9. Set the [[algorithm]] internal slot of publicKey to algorithm.

  10. Set the [[extractable]] internal slot of publicKey to true.

  11. Set the [[usages]] internal slot of publicKey to be the empty list.

  12. Let privateKey be a new CryptoKey object representing the private key of the generated key pair.

  13. Set the [[type]] internal slot of privateKey to "private"

  14. Set the [[algorithm]] internal slot of privateKey to algorithm.

  15. Set the [[extractable]] internal slot of privateKey to extractable.

  16. Set the [[usages]] internal slot of privateKey to be the usage intersection of usages and [ "deriveKey", "deriveBits" ].

  17. Let result be a new CryptoKeyPair dictionary.

  18. Set the publicKey attribute of result to be publicKey.

  19. Set the privateKey attribute of result to be privateKey.

  20. Return the result of converting result to an ECMAScript Object, as defined by [WebIDL].

Derive Bits
  1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

  2. Let publicKey be the public member of normalizedAlgorithm.

  3. If the [[type]] internal slot of publicKey is not "public", then throw an InvalidAccessError.

  4. If the namedCurve attribute of the [[algorithm]] internal slot of publicKey is not equal to the namedCurve property of the [[algorithm]] internal slot of key, then throw an InvalidAccessError.

  5. If the namedCurve property of the [[algorithm]] internal slot of key is "P-256", "P-384" or "P-521":
    1. Perform the ECDH primitive specified in X9.63 Section 5.4.1 with key as the EC private key d and the EC public key represented by the [[handle]] internal slot of publicKey as the EC public key Q.

    2. Let secret be the result of applying the field element to octet string conversion defined in Section ? of X9.63 to the output of the ECDH primitive.

    If the namedCurve property of the [[algorithm]] internal slot of key is a value specified in an applicable specification that specifies the use of that value with ECDH:

    Perform the ECDH key derivation steps specified in that specification, passing in key and publicKey and resulting in secret.

    Otherwise:

    throw a NotSupportedError

  6. If performing the operation results in an error, then throw a OperationError.

  7. If length is null:
    Return secret
    Otherwise:
    If the length of secret in bits is less than length:
    throw an OperationError.
    Otherwise:
    Return the first length bits of secret.
Import Key
  1. Let keyData be the key data to be imported.

  2. If format is "spki":
    1. If usages is not empty then throw a SyntaxError.

    2. Let spki be the result of running the parse a subjectPublicKeyInfo algorithm over keyData

    3. If an error occurred while parsing, then throw a DataError.

    4. If the algorithm object identifier field of the algorithm AlgorithmIdentifier field of spki is not equal to the id-ecPublicKey or id-ecDH object identifiers defined in RFC 5480, then throw a DataError.

    5. If the parameters field of the algorithm AlgorithmIdentifier field of spki is absent, then throw a DataError.

    6. Let params be the parameters field of the algorithm AlgorithmIdentifier field of spki.

    7. If params is not an instance of the ECParameters ASN.1 type defined in RFC 5480 that specifies a namedCurve, then throw a DataError.

    8. Let namedCurve be a string whose initial value is undefined.

    9. If params is equivalent to the secp256r1 object identifier defined in RFC 5480:

      Set namedCurve "P-256".

      If params is equivalent to the secp384r1 object identifier defined in RFC 5480:

      Set namedCurve "P-384".

      If params is equivalent to the secp521r1 object identifier defined in RFC 5480:

      Set namedCurve "P-521".

    10. If namedCurve is not undefined:

      Let key be a new CryptoKey object that represents the Elliptic Curve public key identified by performing the conversion steps defined in Section 2.2 of RFC 5480.

      Otherwise:
      1. Perform any key import steps defined by other applicable specifications, passing format, spki and obtaining namedCurve and key.

      2. If an error occured or there are no applicable specifications, throw a DataError.

    11. If namedCurve is defined, and not equal to the namedCurve member of normalizedAlgorithm, throw a DataError.

    12. If the key value is not a valid point on the Elliptic Curve identified by the namedCurve member of normalizedAlgorithm throw a DataError.

    13. Set the [[type]] internal slot of key to "public"

    14. Let algorithm be a new EcKeyAlgorithm.

    15. Set the name attribute of algorithm to "ECDH".

    16. Set the namedCurve attribute of algorithm to namedCurve.

    17. Set the [[algorithm]] internal slot of key to algorithm.

    If format is "pkcs8":
    1. If usages contains an entry which is not "deriveKey" or "deriveBits" then throw a SyntaxError.

    2. Let privateKeyInfo be the result of running the parse a privateKeyInfo algorithm over keyData.

    3. If an error occurs while parsing, throw a DataError.

    4. If the algorithm object identifier field of the privateKeyAlgorithm PrivateKeyAlgorithm field of privateKeyInfo is not equal to the id-ecPublicKey or id-ecDH object identifiers defined in RFC 5480, throw a DataError.

    5. If the parameters field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo is not present, throw a DataError.

    6. Let params be the parameters field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo.

    7. If params is not an instance of the ECParameters ASN.1 type defined in RFC 5480 that specifies a namedCurve, then throw a DataError.

    8. Let namedCurve be a string whose initial value is undefined.

    9. If params is equivalent to the secp256r1 object identifier defined in RFC 5480:

      Set namedCurve to "P-256".

      If params is equivalent to the secp384r1 object identifier defined in RFC 5480:

      Set namedCurve to "P-384".

      If params is equivalent to the secp521r1 object identifier defined in RFC 5480:

      Set namedCurve to "P-521".

    10. If namedCurve is not undefined:
      1. Let ecPrivateKey be the result of performing the parse an ASN.1 structure algorithm, with data as the privateKey field of privateKeyInfo, structure as the ASN.1 ECPrivateKey structure specified in Section 3 of RFC 5915, and exactData set to true.

      2. If an error occurred while parsing, then throw a DataError.

      3. If the parameters field of ecPrivateKey is present, and is not an instance of the namedCurve ASN.1 type defined in RFC 5480, or does not contain the same object identifier as the parameters field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo, throw a DataError.

      4. Let key be a new CryptoKey object that represents the Elliptic Curve private key identified by performing the conversion steps defined in Section 3 of RFC 5915 using ecPrivateKey.

      Otherwise:
      1. Perform any key import steps defined by other applicable specifications, passing format, privateKeyInfo and obtaining namedCurve and key.

      2. If an error occured or there are no applicable specifications, throw a DataError.

    11. If namedCurve is defined, and not equal to the namedCurve member of normalizedAlgorithm, throw a DataError.

    12. If the key value is not a valid point on the Elliptic Curve identified by the namedCurve member of normalizedAlgorithm throw a DataError.

    13. Set the [[type]] internal slot of key to "private".

    14. Let algorithm be a new EcKeyAlgorithm.

    15. Set the name attribute of algorithm to "ECDH".

    16. Set the namedCurve attribute of algorithm to namedCurve.

    17. Set the [[algorithm]] internal slot of key to algorithm.

    If format is "jwk":
    1. Let jwk be the JsonWebKey dictionary represented by keyData.

    2. If an error occurred while parsing, then throw a DataError.

    3. If the "d" field is present and if usages contains an entry which is not "deriveKey" or "deriveBits" then throw a SyntaxError.

    4. If the "d" field is present and if usages is not empty then throw a SyntaxError.

    5. If the "kty" field of jwk is not "EC", then throw a DataError.

    6. If the "use" field of jwk is present, then throw a DataError.

    7. If the "key_ops" field of jwk is present, and is invalid according to the requirements of JSON Web Key, or it does not contain all of the specified usages values, then throw a DataError.

    8. If the "ext" field of jwk is present and has the value false and extractable is true, then throw a DataError.

    9. Let namedCurve be a string whose value is equal to the "crv" field of jwk.

    10. If namedCurve is not equal to the namedCurve member of normalizedAlgorithm, throw a DataError.

    11. If namedCurve is "P-256", "P-384" or "P-521":
      If the "d" field is present:
      1. If jwk does not meet the requirements of Section 6.2.2 of JSON Web Algorithms, then throw a DataError.

      2. Let key be a new CryptoKey object that represents the Elliptic Curve private key identified by interpreting jwk according to Section 6.2.2 of JSON Web Algorithms.

      3. Set the [[type]] internal slot of Key to "private".

      Otherwise:
      1. If jwk does not meet the requirements of Section 6.2.1 of JSON Web Algorithms, then throw a DataError.

      2. Let key be a new CryptoKey object that represents the Elliptic Curve public key identified by interpreting jwk according to Section 6.2.1 of JSON Web Algorithms.

      3. Set the [[type]] internal slot of Key to "public".

      Otherwise
      1. Perform any key import steps defined by other applicable specifications, passing format, jwk and obtaining key.

      2. If an error occured or there are no applicable specifications, throw a DataError.

    12. If the key value is not a valid point on the Elliptic Curve identified by the namedCurve member of normalizedAlgorithm throw a DataError.

    13. Let algorithm be a new instance of an EcKeyAlgorithm object.

    14. Set the name attribute of algorithm to "ECDH".

    15. Set the namedCurve attribute of algorithm to namedCurve.

    16. Set the [[algorithm]] internal slot of key to algorithm.

    If format is "raw":
    1. If the namedCurve member of normalizedAlgorithm is not a named curve, then throw a DataError.

    2. If usages is not the empty list, then throw a SyntaxError.

    3. If extractable is false, then throw an InvalidAccessError.

    4. If namedCurve is "P-256", "P-384" or "P-521":
      1. Let Q be the elliptic curve point on the curve identified by the namedCurve member of normalizedAlgorithm identified by interpreting keyData according to X9.62 Annex A.

      2. Let key be a new CryptoKey object that represents Q

      Otherwise:
      1. Perform any key import steps defined by other applicable specifications, passing format, keyData and obtaining key.

      2. If an error occured or there are no applicable specifications, throw a DataError.

    5. Let algorithm be a new EcKeyAlgorithm object.

    6. Set the name attribute of algorithm to "ECDH".

    7. Set the namedCurve attribute of algorithm to equal the namedCurve member of normalizedAlgorithm.

    8. Set the [[type]] internal slot of key to "public"

    9. Set the [[algorithm]] internal slot of key to algorithm.

  3. Return key

Export Key
  1. Let key be the CryptoKey to be exported.

  2. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  3. If format is "spki":
    1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

    2. Let data be an instance of the subjectPublicKeyInfo ASN.1 structure defined in RFC 5280 with the following properties:

      • Set the algorithm field to an AlgorithmIdentifier ASN.1 type with the following properties:

        • Set the algorithm object identifier to the OID 1.3.132.112.

        • Set the parameters field to an instance of the ECParameters ASN.1 type defined in RFC 5480 as follows:

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256", "P-384" or "P-521":

          Let keyData be the octet string that represents the Elliptic Curve public key represented by the [[handle]] internal slot of key according to the encoding rules specified in Section 2.2 of RFC 5480 and using the uncompressed form.

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256":

          Set parameters to the namedCurve choice with value equal to the object identifier secp256r1 defined in RFC 5480

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-384":

          Set parameters to the namedCurve choice with value equal to the object identifier secp384r1 defined in RFC 5480

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-521":

          Set parameters to the namedCurve choice with value equal to the object identifier secp521r1 defined in RFC 5480

          Otherwise:
          1. Perform any key export steps defined by other applicable specifications, passing format and the namedCurve attribute of the [[algorithm]] internal slot of key and obtaining namedCurveOid and keyData.

          2. Set parameters to the namedCurve choice with value equal to the object identifier namedCurveOid.

      • Set the subjectPublicKey field to keyData

    If format is "pkcs8":
    1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

    2. Let data be an instance of the privateKeyInfo ASN.1 structure defined in RFC 5280 with the following properties:

      • Set the version field to 0.

      • Set the privateKeyAlgorithm field to an PrivateKeyAlgorithmIdentifier ASN.1 type with the following properties:

        • Set the algorithm object identifier to the OID 1.3.132.112.

        • Set the parameters field to an instance of the ECParameters ASN.1 type defined in RFC 5480 as follows:

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256", "P-384" or "P-521":

          Let keyData be the result of DER-encoding an instance of the ECPrivateKey structure defined in Section 3 of RFC 5915 for the Elliptic Curve private key represented by the [[handle]] internal slot of key and that conforms to the following:

          • The parameters field is present, and is equivalent to the parameters field of the privateKeyAlgorithm field of this PrivateKeyInfo ASN.1 structure.

          • The publicKey field is present and represents the Elliptic Curve public key associated with the Elliptic Curve private key represented by the [[handle]] internal slot of key.

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256":

          Set parameters to the namedCurve choice with value equal to the object identifier secp256r1 defined in RFC 5480

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-384":

          Set parameters to the namedCurve choice with value equal to the object identifier secp384r1 defined in RFC 5480

          If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-521":

          Set parameters to the namedCurve choice with value equal to the object identifier secp521r1 defined in RFC 5480

          Otherwise:
          1. Perform any key export steps defined by other applicable specifications, passing format and the namedCurve attribute of the [[algorithm]] internal slot of key and obtaining namedCurveOid and keyData.

          2. Set parameters to the namedCurve choice with value equal to the object identifier namedCurveOid.

      • Set the privateKey field to keyData.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to "EC".

    3. If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256", "P-384" or "P-521":
      1. If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256":
        Set the crv attribute of jwk to "P-256"
        If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-384":
        Set the crv attribute of jwk to "P-384"
        If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-521":
        Set the crv attribute of jwk to "P-521"
      2. Set the x attribute of jwk according to the definition in Section 6.2.1.2 of JSON Web Algorithms.

      3. Set the y attribute of jwk according to the definition in Section 6.2.1.3 of JSON Web Algorithms.

      4. If the [[type]] internal slot of key is "private"

        Set the d attribute of jwk according to the definition in Section 6.2.2.1 of JSON Web Algorithms.

      Otherwise:
      1. Perform any key export steps defined by other applicable specifications, passing format and the namedCurve attribute of the [[algorithm]] internal slot of key and obtaining namedCurve and a new value of jwk.

      2. Set the crv attribute of jwk to namedCurve.

    4. Set the key_ops attribute of jwk to the usages attribute of key.

    5. Set the ext attribute of jwk to the [[extractable]] internal slot of key.

    6. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    If format is "raw":
    1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

    2. If the namedCurve attribute of the [[algorithm]] internal slot of key is "P-256", "P-384" or "P-521":

      Let data be an octet string representing the Elliptic Curve point Q represented by [[handle]] internal slot of key according to X9.62 Annex A.

      Otherwise:

      Perform any key export steps defined by other applicable specifications, passing format and the namedCurve attribute of the [[algorithm]] internal slot of key and obtaining namedCurve and data.

    3. Let result be a new ArrayBuffer containing data.

  4. Return result.

25. AES-CTR

25.1. Description

This section is non-normative.

The "AES-CTR" algorithm identifier is used to perform encryption and decryption using AES in Counter mode, as described in [NIST SP800-38A].

25.2. Registration

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

Operation Parameters Result
encrypt AesCtrParams ArrayBuffer
decrypt AesCtrParams ArrayBuffer
generateKey AesKeyGenParams CryptoKey
importKey None CryptoKey
exportKey None object
get key length AesDerivedKeyParams Integer

25.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.
required BufferSource counter;
// The length, in bits, of the rightmost part of the counter block
// that is incremented.
[EnforceRange] required octet length;
};
          
IDL

dictionary AesKeyAlgorithm : KeyAlgorithm {
// The length, in bits, of the key.
required unsigned short length;
};
          

25.5. AesKeyGenParams dictionary

IDL

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

25.6. AesDerivedKeyParams dictionary

IDL

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

25.7. Operations

Encrypt
  1. If the counter member of normalizedAlgorithm does not have length 16 bytes, then throw an OperationError.

  2. If the length member of normalizedAlgorithm is zero or is greater than 128, then throw an OperationError.

  3. Let ciphertext be the result of performing the CTR Encryption operation described in Section 6.5 of [NIST SP800-38A] using AES as the block cipher, the contents of the counter member of normalizedAlgorithm as the initial value of the counter block, the length member of normalizedAlgorithm as the input parameter m to the standard counter block incrementing function defined in Appendix B.1 of [NIST SP800-38A] and the contents of plaintext as the input plaintext.

  4. Return ciphertext.

Decrypt
  1. If the counter member of normalizedAlgorithm does not have length 16 bytes, then throw an OperationError.

  2. If the length member of normalizedAlgorithm is zero or is greater than 128, then throw an OperationError.

  3. Let plaintext be the result of performing the CTR Decryption operation described in Section 6.5 of [NIST SP800-38A] using AES as the block cipher, the contents of the counter member of normalizedAlgorithm as the initial value of the counter block, the length member of normalizedAlgorithm as the input parameter m to the standard counter block incrementing function defined in Appendix B.1 of [NIST SP800-38A] and the contents of ciphertext as the input ciphertext.

  4. Return plaintext.

Generate Key
  1. If usages contains any entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If the length member of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError.

  3. Generate an AES key of length equal to the length member of normalizedAlgorithm.

  4. If the key generation step fails, then throw an OperationError.

  5. Let key be a new CryptoKey object representing the generated AES key.

  6. Let algorithm be a new AesKeyAlgorithm.

  7. Set the name attribute of algorithm to "AES-CTR".

  8. Set the length attribute of algorithm to equal the length member of normalizedAlgorithm.

  9. Set the [[algorithm]] internal slot of key to algorithm.

  10. Set the [[extractable]] internal slot of key to be extractable.

  11. Set the [[usages]] internal slot of key to be usages.

  12. Return key.

Import Key
  1. If usages contains an entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If format is "raw":
    1. Let data be the octet string contained in keyData.

    2. If the length in bits of data is not 128, 192 or 256 then throw a DataError.

    If format is "jwk":
    1. Let jwk be the JsonWebKey dictionary represented by keyData.

    2. If the "kty" field of jwk is not "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms, then throw a DataError.

    4. Let data be the octet string obtained by decoding the "k" field of jwk.

    5. If data has length 128 bits:
      If the "alg" field of jwk is present, and is not "A128CTR", then throw a DataError.
      If data has length 192 bits:
      If the "alg" field of jwk is present, and is not "A192CTR", then throw a DataError.
      If data has length 256 bits:
      If the "alg" field of jwk is present, and is not "A256CTR", then throw a DataError.
      Otherwise:
      throw a DataError.
    6. If the "use" field of jwk is present, and is not "enc", then throw a DataError.

    7. If the "key_ops" field of jwk is present, and is invalid according to the requirements of JSON Web Key or does not contain all of the specified usages values, then throw a DataError.

    8. If the "ext" field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError.
  3. Let key be a new CryptoKey object representing an AES key with value data.

  4. Let algorithm be a new AesKeyAlgorithm.

  5. Set the name attribute of algorithm to "AES-CTR".

  6. Set the length attribute of algorithm to the length, in bits, of data.

  7. Set the [[algorithm]] internal slot of key to algorithm.

  8. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw":
    1. Let data be the raw octets of the key represented by [[handle]] internal slot of key.

    2. Let result be a new ArrayBuffer containing data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing the raw octets of the key represented by [[handle]] internal slot of key, encoded according to Section 6.4 of JSON Web Algorithms.

    4. If the length attribute of key is 128:
      Set the alg attribute of jwk to the string "A128CTR".
      If the length attribute of key is 192:
      Set the alg attribute of jwk to the string "A192CTR".
      If the length attribute of key is 256:
      Set the alg attribute of jwk to the string "A256CTR".
    5. Set the key_ops attribute of jwk to equal the [[usages]] internal slot of key.

    6. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    7. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  3. Return result.

Get key length
  1. If the length member of normalizedDerivedKeyAlgorithm is not 128, 192 or 256, then throw a DataError.

  2. Return the length member of normalizedDerivedKeyAlgorithm.

26. AES-CBC

26.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 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#7, as described by Section 10.3, step 2, of [RFC2315].

26.2. Registration

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

Operation Parameters Result
encrypt AesCbcParams ArrayBuffer
decrypt AesCbcParams ArrayBuffer
generateKey AesKeyGenParams CryptoKey
importKey None CryptoKey
exportKey None object
get key length AesDerivedKeyParams Integer

26.3. AesCbcParams dictionary

IDL

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

26.4. Operations

Encrypt
  1. If the iv member of normalizedAlgorithm does not have length 16 bytes, then throw an OperationError.

  2. Let paddedPlaintext be the result of adding padding octets to the contents of ciphertext according to the procedure defined in Section 10.3 of [RFC2315], step 2, with a value of k of 16.

  3. Let ciphertext be the result of performing the CBC Encryption operation described in Section 6.2 of [NIST SP800-38A] using AES as the block cipher, the contents of the iv member of normalizedAlgorithm as the IV input parameter and paddedPlaintext as the input plaintext.

  4. Return ciphertext.

Decrypt
  1. If the iv member of normalizedAlgorithm does not have length 16 bytes, then throw an OperationError.

  2. Let paddedPlaintext be the result of performing the CBC Decryption operation described in Section 6.2 of [NIST SP800-38A] using AES as the block cipher, the contents of the iv member of normalizedAlgorithm as the IV input parameter and the contents of ciphertext as the input ciphertext.

  3. Let p be the value of the last octet of paddedPlaintext.

  4. If p is zero or greater than 16, or if any of the last p octets of paddedPlaintext have a value which is not p, then throw an OperationError.

  5. Let plaintext be the result of removing p octets from the end of paddedPlaintext.

  6. Return plaintext.

Generate Key
  1. If usages contains any entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If the length member of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError.

  3. Generate an AES key of length equal to the length member of normalizedAlgorithm.

  4. If the key generation step fails, then throw an OperationError.

  5. Let key be a new CryptoKey object representing the generated AES key.

  6. Let algorithm be a new AesKeyAlgorithm.

  7. Set the name attribute of algorithm to "AES-CBC".

  8. Set the length attribute of algorithm to equal the length member of normalizedAlgorithm.

  9. Set the [[algorithm]] internal slot of key to algorithm.

  10. Set the [[extractable]] internal slot of key to be extractable.

  11. Set the [[usages]] internal slot of key to be usages.

  12. Return key.

Import Key
  1. If usages contains an entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If format is "raw":
    1. Let data be the octet string contained in keyData.

    2. If the length in bits of data is not 128, 192 or 256 then throw a DataError.

    If format is "jwk":
    1. Let jwk be the JsonWebKey dictionary represented by keyData.

    2. If the "kty" field of jwk is not to "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms, then throw a DataError.

    4. Let data be the octet string obtained by decoding the "k" field of jwk.

    5. If data has length 128 bits:
      If the "alg" field of jwk is present, and is not "A128CBC", then throw a DataError.
      If data has length 192 bits:
      If the "alg" field of jwk is present, and is not "A192CBC", then throw a DataError.
      If data has length 256 bits:
      If the "alg" field of jwk is present, and is not "A256CBC", then throw a DataError.
      Otherwise:
      throw a DataError.
    6. If the "use" field of jwk is present, and is not "enc", then throw a DataError.

    7. If the "key_ops" field of jwk is present, and is invalid according to the requirements of JSON Web Key or does not contain all of the specified usages values, then throw a DataError.

    8. If the "ext" field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError
  3. Let key be a new CryptoKey object representing an AES key with value data.

  4. Let algorithm be a new AesKeyAlgorithm.

  5. Set the name attribute of algorithm to "AES-CBC".

  6. Set the length attribute of algorithm to the length, in bits, of data.

  7. Set the [[algorithm]] internal slot of key to algorithm.

  8. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw":
    1. Let data be the raw octets of the key represented by [[handle]] internal slot of key.

    2. Let result be a new ArrayBuffer containing data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing the raw octets of the key represented by [[handle]] internal slot of key, encoded according to Section 6.4 of JSON Web Algorithms.

    4. If the length attribute of key is 128:
      Set the alg attribute of jwk to the string "A128CBC".
      If the length attribute of key is 192:
      Set the alg attribute of jwk to the string "A192CBC".
      If the length attribute of key is 256:
      Set the alg attribute of jwk to the string "A256CBC".
    5. Set the key_ops attribute of jwk to equal the usages attribute of key.

    6. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    7. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  3. Return result.

Get key length
  1. If the length member of normalizedDerivedKeyAlgorithm is not 128, 192 or 256, then throw an OperationError.

  2. Return the length member of normalizedDerivedKeyAlgorithm.

27. AES-CMAC

27.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 SP800-38B].

27.2. Registration

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

Operation Parameters Result
sign AesCmacParams ArrayBuffer
verify AesCmacParams boolean
generateKey AesKeyGenParams CryptoKey
importKey None CryptoKey
exportKey None object
get key length AesDerivedKeyParams Integer

27.3. AesCmacParams dictionary

IDL

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

27.4. Operations

Sign
  1. Let length equal the length member of normalizedAlgorithm, if present, and 128 otherwise.

  2. If length is zero or greater than 128, then throw an OperationError.

  3. Let mac be the result of performing the MAC Generation operation described in Section 6.2 of [NIST SP800-38B] using AES as the block cipher, length as the value of the MAC length parameter, Tlen, and message as the message, M.

  4. Return mac.

Verify
  1. Let length equal the length member of normalizedAlgorithm, if present, and 128 otherwise.

  2. If length is zero or greater than 128, then throw an OperationError.

  3. Let output be the result of performing the MAC Verification operation described in Section 6.3 of [NIST SP 800-38B] using AES as the block cipher, length as the value of the MAC length parameter, Tlen, message as the message, M and signature as the received MAC, T'.

  4. Return true if output is VALID and false otherwise.

Generate Key
  1. If usages contains any entry which is not "sign" or "verify", then throw a SyntaxError.

  2. If the length member of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError.

  3. Generate an AES key of length equal to the length member of normalizedAlgorithm.

  4. If the key generation step fails, then throw an OperationError.

  5. Let key be a new CryptoKey object representing the generated AES key.

  6. Let algorithm be a new AesKeyAlgorithm.

  7. Set the name attribute of algorithm to "AES-CMAC".

  8. Set the length attribute of algorithm to equal the length member of normalizedAlgorithm.

  9. Set the [[algorithm]] internal slot of key to algorithm.

  10. Set the [[extractable]] internal slot of key to be extractable.

  11. Set the [[usages]] internal slot of key to be usages.

  12. Return key.

Import Key
  1. If usages contains an entry which is not "sign" or "verify", then throw a SyntaxError.

  2. If format is "raw":
    1. Let data be the octet string contained in keyData.

    2. If the length in bits of data is not 128, 192 or 256 then throw a DataError.

    If format is "jwk":
    1. Let jwk be the JsonWebKey dictionary represented by keyData.

    2. If the "kty" field of jwk is not to "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms, then throw a DataError.

    4. Let data be the octet string obtained by decoding the "k" field of jwk.

    5. If data has length 128 bits:
      If the "alg" field of jwk is present, and is not "A128CMAC", then throw a DataError.
      If data has length 192 bits:
      If the "alg" field of jwk is present, and is not "A192CMAC", then throw a DataError.
      If data has length 256 bits:
      If the "alg" field of jwk is present, and is not "A256CMAC", then throw a DataError.
      Otherwise:
      throw a DataError.
    6. If the "use" field of jwk is present, and is not "enc", then throw a DataError.

    7. If the "key_ops" field of jwk is present, and is invalid according to the requirements of JSON Web Key or does not contain all of the specified usages values, then throw a DataError.

    8. If the "ext" field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError.
  3. Let key be a new CryptoKey object representing an AES key with value data.

  4. Let algorithm be a new AesKeyAlgorithm.

  5. Set the name attribute of algorithm to "AES-CMAC".

  6. Set the length attribute of algorithm to the length, in bits, of data.

  7. Set the [[algorithm]] internal slot of key to algorithm.

  8. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw":
    1. Let data be the raw octets of the key represented by [[handle]] internal slot of key.

    2. Let result be a new ArrayBuffer containing data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing the raw octets of the key represented by [[handle]] internal slot of key, encoded according to Section 6.4 of JSON Web Algorithms.

    4. If the length attribute of key is 128:
      Set the alg attribute of jwk to the string "A128CMAC".
      If the length attribute of key is 192:
      Set the alg attribute of jwk to the string "A192CMAC".
      If the length attribute of key is 256:
      Set the alg attribute of jwk to the string "A256CMAC".
    5. Set the key_ops attribute of jwk to equal the usages attribute of key.

    6. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    7. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  3. Return result.

Get key length
  1. If the length member of normalizedDerivedKeyAlgorithm is not 128, 192 or 256, then throw an OperationError.

  2. Return the length member of normalizedDerivedKeyAlgorithm.

28. AES-GCM

28.1. Description

This section is non-normative.

The "AES-GCM" algorithm identifier is used to perform authenticated encryption and decryption using AES in Galois/Counter Mode mode, as described in [NIST SP 800-38D].

28.2. Registration

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

Operation Parameters Result
encrypt AesGcmParams ArrayBuffer
decrypt AesGcmParams ArrayBuffer
generateKey AesKeyGenParams CryptoKey
importKey None CryptoKey
exportKey None object
get key length AesDerivedKeyParams Integer

28.3. AesGcmParams dictionary

IDL

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

28.4. Operations

Encrypt
  1. If plaintext has a length greater than 2^39 - 256 bytes, then throw an OperationError.

  2. If the iv member of normalizedAlgorithm has a length greater than 2^64 - 1 bytes, then throw an OperationError.

  3. If the additionalData member of normalizedAlgorithm is present and has a length greater than 2^64 - 1 bytes, then throw an OperationError.

  4. If the tagLength member of normalizedAlgorithm is not present:
    Let tagLength be 128.
    If the tagLength member of normalizedAlgorithm is one of 32, 64, 96, 104, 112, 120 or 128:
    Let tagLength be equal to the tagLength member of normalizedAlgorithm
    Otherwise:
    throw an OperationError.
  5. Let additionalData be the contents of the additionalData member of normalizedAlgorithm if present or the empty octet string otherwise.

  6. Let C and T be the outputs that result from performing the Authenticated Encryption Function described in Section 7.1 of [NIST SP800-38D] using AES as the block cipher, the contents of the iv member of normalizedAlgorithm as the IV input parameter, the contents of additionalData as the A input parameter, tagLength as the t pre-requisite and the contents of plaintext as the input plaintext.

  7. Return a new ArrayBuffer containing C | T where '|' denotes concatenation.

Decrypt
  1. If the tagLength member of normalizedAlgorithm is not present:
    Let tagLength be 128.
    If the tagLength member of normalizedAlgorithm is one of 32, 64, 96, 104, 112, 120 or 128:
    Let tagLength be equal to the tagLength member of normalizedAlgorithm
    Otherwise:
    throw an OperationError.
  2. If plaintext has a length less than tagLength bits, then throw an OperationError.

  3. If the iv member of normalizedAlgorithm has a length greater than 2^64 - 1 bytes, then throw an OperationError.

  4. If the additionalData member of normalizedAlgorithm is present and has a length greater than 2^64 - 1 bytes, then throw an OperationError.

  5. Let tag be the last tagLength bits of ciphertext.

  6. Let actualCiphertext be the result of removing the last tagLength bits from ciphertext.

  7. Let additionalData be the contents of the additionalData member of normalizedAlgorithm if present or the empty octet string otherwise.

  8. Perform the Authenticated Decryption Function described in Section 7.2 of [NIST SP800-38D] using AES as the block cipher, the contents of the iv member of normalizedAlgorithm as the IV input parameter, the contents of additionalData as the A input parameter, tagLength as the t pre-requisite, the contents of actualCiphertext as the input ciphertext, C and the contents of tag as the authentication tag, T.

    If the result of the algorithm is the indication of inauthenticity, "FAIL":
    throw an OperationError
    Otherwise:
    Let plaintext be the output P of the Authenticated Decryption Function.
  9. Return a new ArrayBuffer containing plaintext.

Generate Key
  1. If usages contains any entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If the length member of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError.

  3. Generate an AES key of length equal to the length member of normalizedAlgorithm.

  4. If the key generation step fails, then throw an OperationError.

  5. Let key be a new CryptoKey object representing the generated AES key.

  6. Let algorithm be a new AesKeyAlgorithm.

  7. Set the name attribute of algorithm to "AES-GCM".

  8. Set the length attribute of algorithm to equal the length member of normalizedAlgorithm.

  9. Set the [[algorithm]] internal slot of key to algorithm.

  10. Set the [[extractable]] internal slot of key to be extractable.

  11. Set the [[usages]] internal slot of key to be usages.

  12. Return key.

Import Key
  1. If usages contains an entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If format is "raw":
    1. Let data be the octet string contained in keyData.

    2. If the length in bits of data is not 128, 192 or 256 then throw a DataError.

    If format is "jwk":
    1. Let jwk be the JsonWebKey dictionary represented by keyData.

    2. If the "kty" field of jwk is not "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms, then throw a DataError.

    4. Let data be the octet string obtained by decoding the "k" field of jwk.

    5. If data has length 128 bits:
      If the "alg" field of jwk is present, and is not "A128GCM", then throw a DataError.
      If data has length 192 bits:
      If the "alg" field of jwk is present, and is not "A192GCM", then throw a DataError.
      If data has length 256 bits:
      If the "alg" field of jwk is present, and is not "A256GCM", then throw a DataError.
      Otherwise:
      throw a DataError.
    6. If the "use" field of jwk is present, and is not "enc", then throw a DataError.

    7. If the "key_ops" field of jwk is present, and is invalid according to the requirements of JSON Web Key or does not contain all of the specified usages values, then throw a DataError.

    8. If the "ext" field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError.
  3. Let key be a new CryptoKey object representing an AES key with value data.

  4. Let algorithm be a new AesKeyAlgorithm.

  5. Set the name attribute of algorithm to "AES-GCM".

  6. Set the length attribute of algorithm to the length, in bits, of data.

  7. Set the [[algorithm]] internal slot of key to algorithm.

  8. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw":
    1. Let data be the raw octets of the key represented by [[handle]] internal slot of key.

    2. Let result be a new ArrayBuffer containing data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing the raw octets of the key represented by [[handle]] internal slot of key, encoded according to Section 6.4 of JSON Web Algorithms.

    4. If the length attribute of key is 128:
      Set the alg attribute of jwk to the string "A128GCM".
      If the length attribute of key is 192:
      Set the alg attribute of jwk to the string "A192GCM".
      If the length attribute of key is 256:
      Set the alg attribute of jwk to the string "A256GCM".
    5. Set the key_ops attribute of jwk to equal the usages attribute of key.

    6. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    7. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  3. Return result.

Get key length
  1. If the length member of normalizedDerivedKeyAlgorithm is not 128, 192 or 256, then throw an OperationError.

  2. Return the length member of normalizedDerivedKeyAlgorithm.

29. AES-CFB

29.1. Description

This section is non-normative.

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

29.2. Registration

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

Operation Parameters Result
encrypt AesCfbParams ArrayBuffer
decrypt AesCfbParams ArrayBuffer
generateKey AesKeyGenParams CryptoKey
importKey None CryptoKey
exportKey None object
get key length AesDerivedKeyParams Integer

29.3. AesCfbParams dictionary

IDL

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

29.4. Operations

Encrypt
  1. If the iv member of normalizedAlgorithm does not have length 16 bytes, then throw an OperationError.

  2. Let ciphertext be the result of performing the CFB Encryption operation described in Section 6.3 of [NIST SP800-38A] using AES as the block cipher, the contents of the iv member of normalizedAlgorithm as the IV input parameter, the value 8 as the input parameter s, and the contents ofplaintext as the input plaintext.

  3. Return ciphertext.

Decrypt
  1. If the iv member of normalizedAlgorithm does not have length 16 bytes, then throw an OperationError.

  2. Let plaintext be the result of performing the CFB Decryption operation described in Section 6.3 of [NIST SP800-38A] using AES as the block cipher, the contents of the iv member of normalizedAlgorithm as the IV input parameter, the the value 8 as the input parameter s, and the contents of ciphertext as the input ciphertext.

  3. Return plaintext.

Generate Key
  1. If usages contains any entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If the length member of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError.

  3. Generate an AES key of length equal to the length member of normalizedAlgorithm.

  4. If the key generation step fails, then throw an OperationError.

  5. Let key be a new CryptoKey object representing the generated AES key.

  6. Let algorithm be a new AesKeyAlgorithm.

  7. Set the name attribute of algorithm to "AES-CFB-8".

  8. Set the length attribute of algorithm to equal the length member of normalizedAlgorithm.

  9. Set the [[algorithm]] internal slot of key to algorithm.

  10. Set the [[extractable]] internal slot of key to be extractable.

  11. Set the [[usages]] internal slot of key to be usages.

  12. Return key.

Import Key
  1. If usages contains an entry which is not one of "encrypt", "decrypt", "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If format is "raw":
    1. Let data be the octet string contained in keyData.

    2. If the length in bits of data is not 128, 192 or 256 then throw a DataError.

    If format is "jwk":
    1. Let jwk be the JsonWebKey dictionary represented by keyData.

    2. If the "kty" field of jwk is not "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms, then throw a DataError.

    4. Let data be the octet string obtained by decoding the "k" field of jwk.

    5. If data has length 128 bits:
      If the "alg" field of jwk is present, and is not "A128CFB8", then throw a DataError.
      If data has length 192 bits:
      If the "alg" field of jwk is present, and is not "A192CFB8", then throw a DataError.
      If data has length 256 bits:
      If the "alg" field of jwk is present, and is not "A256CFB8", then throw a DataError.
      Otherwise:
      throw a DataError.
    6. If the "use" field of jwk is present, and is not "enc", then throw a DataError.

    7. If the "key_ops" field of jwk is present, and is invalid according to the requirements of JSON Web Key or does not contain all of the specified usages values, then throw a DataError.

    8. If the "ext" field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError.
  3. Let key be a new CryptoKey object representing an AES key with value data.

  4. Let algorithm be a new AesKeyAlgorithm.

  5. Set the name attribute of algorithm to "AES-CFB-8".

  6. Set the length attribute of algorithm to the length, in bits, of data.

  7. Set the [[algorithm]] internal slot of key to algorithm.

  8. Set the [[extractable]] internal slot of key to extractable.

  9. Set the [[usages]] internal slot of key to the normalized value of usages.

  10. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw":
    1. Let data be the raw octets of the key represented by [[handle]] internal slot of key.

    2. Let result be a new ArrayBuffer containing data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing the raw octets of the key represented by [[handle]] internal slot of key, encoded according to Section 6.4 of JSON Web Algorithms.

    4. If the length attribute of key is 128:
      Set the alg attribute of jwk to the string "A128CFB8".
      If the length attribute of key is 192:
      Set the alg attribute of jwk to the string "A192CFB8".
      If the length attribute of key is 256:
      Set the alg attribute of jwk to the string "A256CFB8".
    5. Set the key_ops attribute of jwk to equal the usages attribute of key.

    6. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    7. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  3. Return result.

Get key length
  1. If the length property of normalizedDerivedKeyAlgorithm is not 128, 192 or 256, then throw an OperationError.

  2. Return the length property of normalizedDerivedKeyAlgorithm.

30. AES-KW

30.1. Description

This section is non-normative.

The "AES-KW" algorithm identifier is used to perform key wrapping using AES, as described in [RFC3394].

30.2. Registration

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

Operation Parameters Result
wrapKey None ArrayBuffer
unwrapKey None ArrayBuffer
generateKey AesKeyGenParams CryptoKey
importKey None CryptoKey
exportKey None object
get key length AesDerivedKeyParams Integer

30.3. Operations

Wrap Key
  1. If plaintext is not a multiple of 64 bits in length, then throw an OperationError.

  2. Let ciphertext be the result of performing the Key Wrap operation described in Section 2.2.1 of [RFC3394] with plaintext as the plaintext to be wrapped and using the default Initial Value defined in Section 2.2.3.1 of the same document.

  3. Return ciphertext.

Unwrap Key
  1. Let plaintext be the result of performing the Key Unwrap operation described in Section 2.2.2 of [RFC3394] with ciphertext as the input ciphertext and using the default Initial Value defined in Section 2.2.3.1 of the same document.

  2. If the Key Unwrap operation returns an error, then throw an OperationError.

  3. Return plaintext.

Generate Key
  1. If usages contains any entry which is not one of "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If the length property of normalizedAlgorithm is not equal to one of 128, 192 or 256, then throw an OperationError.

  3. If the key generation step fails, then throw an OperationError.

  4. Let key be a new CryptoKey object representing the generated AES key.

  5. Let algorithm be a new AesKeyAlgorithm.

  6. Set the name attribute of algorithm to "AES-KW".

  7. Set the length attribute of algorithm to equal the length property of normalizedAlgorithm.

  8. Set the [[algorithm]] internal slot of key to algorithm.

  9. Set the [[extractable]] internal slot of key to be extractable.

  10. Set the [[usages]] internal slot of key to be usages.

  11. Return key.

Import Key
  1. If usages contains an entry which is not one of "wrapKey" or "unwrapKey", then throw a SyntaxError.

  2. If format is "raw":
    1. Let data be the octet string contained in keyData.

    2. If the length in bits of data is not 128, 192 or 256 then throw a DataError.

    If format is "jwk":
    1. Let jwk be the JsonWebKey dictionary represented by keyData.

    2. If the "kty" field of jwk is not "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms, then throw a DataError.

    4. Let data be the octet string obtained by decoding the "k" field of jwk.

    5. If data has length 128 bits:
      If the "alg" field of jwk is present, and is not "A128KW", then throw a DataError.
      If data has length 192 bits:
      If the "alg" field of jwk is present, and is not "A192KW", then throw a DataError.
      If data has length 256 bits:
      If the "alg" field of jwk is present, and is not "A256KW", then throw a DataError.
      Otherwise:
      throw a DataError.
    6. If the "use" field of jwk is present, and is not "enc", then throw a DataError.

    7. If the "key_ops" field of jwk is present, and is invalid according to the requirements of JSON Web Key or does not contain all of the specified usages values, then throw a DataError.

    8. If the "ext" field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError.
  3. Let key be a new CryptoKey object representing an AES key with value data.

  4. Let algorithm be a new AesKeyAlgorithm.

  5. Set the name attribute of algorithm to "AES-KW".

  6. Set the length attribute of algorithm to the length, in bits, of data.

  7. Set the [[algorithm]] internal slot of key to algorithm.

  8. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw":
    1. Let data be the raw octets of the key represented by [[handle]] internal slot of key.

    2. Let result be a new ArrayBuffer containing data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing the raw octets of the key represented by [[handle]] internal slot of key, encoded according to Section 6.4 of JSON Web Algorithms.

    4. If the length attribute of key is 128:
      Set the alg attribute of jwk to the string "A128KW".
      If the length attribute of key is 192:
      Set the alg attribute of jwk to the string "A192KW".
      If the length attribute of key is 256:
      Set the alg attribute of jwk to the string "A256KW".
    5. Set the key_ops attribute of jwk to equal the usages attribute of key.

    6. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    7. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  3. Return result.

Get key length
  1. If the length member of normalizedDerivedKeyAlgorithm is not 128, 192 or 256, then throw an OperationError.

  2. Return the length member of normalizedDerivedKeyAlgorithm.

31. HMAC

31.1. Description

This section is non-normative.

The HMAC algorithm calculates and verifies hash-based message authentication codes according to [FIPS PUB 198-1] using the SHA hash functions defined in this specification.

Other specifications may specify the use of additional hash algorithms with HMAC. Such specifications must define the digest operation for the additional hash algorithms and key import steps and key export steps for HMAC.

31.2. Registration

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

Operation Parameters Result
sign None ArrayBuffer
verify None boolean
generateKey HmacKeyGenParams CryptoKey
importKey HmacImportParams CryptoKey
exportKey None object
get key length HmacImportParams Integer

31.3. HmacImportParams dictionary

IDL

dictionary HmacImportParams : Algorithm {
// The inner hash function to use.
HashAlgorithmIdentifier hash;
// The length (in bits) of the key.
[EnforceRange] unsigned long length;
};
          

31.4. HmacKeyAlgorithm dictionary

IDL

dictionary HmacKeyAlgorithm : KeyAlgorithm {
// The inner hash function to use.
required KeyAlgorithm hash;
// The length (in bits) of the key.
required unsigned long length;
};
          

31.5. HmacKeyGenParams dictionary

IDL

dictionary HmacKeyGenParams : Algorithm {
// The inner hash function to use.
required HashAlgorithmIdentifier hash;
// The length (in bits) of the key to generate. If unspecified, the
// recommended length will be used, which is the size of the associated hash function's block
// size.
[EnforceRange] unsigned long length;
};
          

31.6. Operations

Sign
  1. Let mac be the result of performing the MAC Generation operation described in Section 4 of [FIPS PUB 198-1] using the key represented by [[handle]] internal slot of key, the hash function identified by the hash attribute of the [[algorithm]] internal slot of key and message as the input data text.

  2. Return mac.

Verify
  1. Let mac be the result of performing the MAC Generation operation described in Section 4 of [FIPS PUB 198-1] using the key represented by [[handle]] internal slot of key, the hash function identified by the hash attribute of the [[algorithm]] internal slot of key and message as the input data text.

  2. Return true if mac is equal to signature and false otherwise.

Generate Key
  1. If usages contains any entry which is not "sign" or "verify", then throw a SyntaxError.

  2. If the length member of normalizedAlgorithm is not present:
    Let length be the block size in bits of the hash function identified by the hash member of normalizedAlgorithm.
    Otherwise, if the length member of normalizedAlgorithm is non-zero:
    Let length be equal to the length member of normalizedAlgorithm.
    Otherwise:
    throw an OperationError.
  3. Generate a key of length length bits.

  4. If the key generation step fails, then throw an OperationError.

  5. Let key be a new CryptoKey object representing the generated key.

  6. Let algorithm be a new HmacKeyAlgorithm.

  7. Set the name attribute of algorithm to "HMAC".

  8. Let hash be a new KeyAlgorithm.

  9. Set the name attribute of hash to equal the name member of the hash member of normalizedAlgorithm.

  10. Set the hash attribute of algorithm to hash.

  11. Set the [[algorithm]] internal slot of key to algorithm.

  12. Set the [[extractable]] internal slot of key to be extractable.

  13. Set the [[usages]] internal slot of key to be usages.

  14. Return key.

Import Key
  1. Let keyData be the key data to be imported.

  2. If usages contains an entry which is not "sign" or "verify", then throw a SyntaxError.

  3. Let hash be a new KeyAlgorithm.

  4. If format is "raw":
    1. Let data be the octet string contained in keyData.

    2. If the hash member of normalizedAlgorithm is present:
      Set hash to equal the hash member of normalizedAlgorithm.
      Otherwise:
      throw a TypeError.
    If format is "jwk":
    1. Let jwk be the JsonWebKey dictionary represented by keyData.

    2. If the "kty" field of jwk is not "oct", then throw a DataError.

    3. If jwk does not meet the requirements of Section 6.4 of JSON Web Algorithms, then throw a DataError.

    4. Let data be the octet string obtained by decoding the "k" field of jwk.

    5. If the hash member of normalizedAlgorithm is present:
      1. Set the hash to equal the hash member of normalizedAlgorithm.

      2. If the name attribute of hash is "SHA-1":
        If the "alg" field of jwk is present and is not "HS1", then throw a DataError.
        If If the name attribute of hash is "SHA-256":
        If the "alg" field of jwk is present and is not "HS256", then throw a DataError.
        If If the name attribute of hash is "SHA-384":
        If the "alg" field of jwk is present and is not "HS384", then throw a DataError.
        If If the name attribute of hash is "SHA-512":
        If the "alg" field of jwk is present and is not "HS512", then throw a DataError.
        Otherwise, if the name attribute of hash is defined in another applicable specification:
        Perform any key import steps defined by other applicable specifications, passing format, jwk and hash and obtaining hash.
        Otherwise:
        throw a DataError.
      Otherwise:
      1. If the alg field of jwk is not present, then throw a DataError.

      2. If the "alg" field of jwk is "HS1":
        Set the name attribute of hash to "SHA-1".
        If the "alg" field of jwk is "HS256":
        Set the name attribute of hash to "SHA-256".
        If the "alg" field of jwk is "HS384":
        Set the name attribute of hash to "SHA-384".
        If the "alg" field of jwk is "HS512":
        Set the name attribute of hash to "SHA-512".
        Otherwise:
        Perform any key import steps defined by other applicable specifications, passing format, jwk and undefined and obtaining hash.
    6. If the "use" field of jwk is present, and is not "sign", then throw a DataError.

    7. If the "key_ops" field of jwk is present, and is invalid according to the requirements of JSON Web Key or does not contain all of the specified usages values, then throw a DataError.

    8. If the "ext" field of jwk is present and has the value false and extractable is true, then throw a DataError.

    Otherwise:
    throw a NotSupportedError.
  5. Let length be equivalent to the length, in octets, of data, multiplied by 8.

  6. If length is zero then throw a DataError.

  7. If the length member of normalizedAlgorithm is present:
    If the length member of normalizedAlgorithm is greater than length:
    throw a DataError.
    If the length member of normalizedAlgorithm, is less than or equal to length minus eight:
    throw a DataError.
    Otherwise:
    Set length equal to the length member of normalizedAlgorithm.
  8. Let key be a new CryptoKey object representing an HMAC key with the first length bits of data.

  9. Let algorithm be a new HmacKeyAlgorithm.

  10. Set the name attribute of algorithm to "HMAC".

  11. Set the length attribute of algorithm to length.

  12. Set the hash attribute of algorithm to hash.

  13. Set the [[algorithm]] internal slot of key to algorithm.

  14. Return key.

Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw":
    1. Let data be the raw octets of the key represented by [[handle]] internal slot of key.

    2. Let result be a new ArrayBuffer containing data.

    If format is "jwk":
    1. Let jwk be a new JsonWebKey dictionary.

    2. Set the kty attribute of jwk to the string "oct".

    3. Set the k attribute of jwk to be a string containing the raw octets of the key represented by [[handle]] internal slot of key, encoded according to Section 6.4 of JSON Web Algorithms.

    4. Let algorithm be the [[algorithm]] internal slot of key.

    5. Let hash be the hash attribute of algorithm.

    6. If the name attribute of hash is "SHA-1":
      Set the alg attribute of jwk to the string "HS1".
      If the name attribute of hash is "SHA-256":
      Set the alg attribute of jwk to the string "HS256".
      If the name attribute of hash is "SHA-384":
      Set the alg attribute of jwk to the string "HS384".
      If the name attribute of hash is "SHA-512":
      Set the alg attribute of jwk to the string "HS512".
      Otherwise, the name attribute of hash is defined in another applicable specification:
      1. Perform any key export steps defined by other applicable specifications, passing format and key and obtaining alg.

      2. Set the alg attribute of jwk to alg.

    7. Set the key_ops attribute of jwk to equal the usages attribute of key.

    8. Set the ext attribute of jwk to equal the [[extractable]] internal slot of key.

    9. Let result be the result of converting jwk to an ECMAScript Object, as defined by [WebIDL].

    Otherwise:

    throw a NotSupportedError.

  3. Return result.

Get key length
  1. If the length member of normalizedDerivedKeyAlgorithm is not present:
    1. If the hash member of normalizedDerivedKeyAlgorithm is not present, throw a TypeError.

    2. Let length be the block size in bytes of the hash function identified by the hash member of normalizedDerivedKeyAlgorithm.

    Otherwise, if the length member of normalizedDerivedKeyAlgorithm is non-zero:
    Let length be equal to the length member of normalizedDerivedKeyAlgorithm.
    Otherwise:
    throw a TypeError.
  2. Return length.

32. Diffie-Hellman

32.1. Description

This section is non-normative.

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

32.2. Registration

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

Operation Parameters Result
generateKey DhKeyGenParams CryptoKeyPair
deriveBits DhKeyDeriveParams Octet string
importKey DhImportKeyParams CryptoKey
exportKey None object

32.3. DhKeyGenParams dictionary

IDL

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

32.4. DhKeyAlgorithm dictionary

IDL

dictionary DhKeyAlgorithm : KeyAlgorithm {
// The prime p.
required BigInteger prime;
// The base g.
required BigInteger generator;
};
          

32.5. DhKeyDeriveParams dictionary

IDL

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

32.6. DhImportKeyParams dictionary

IDL

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

32.7. Operations

Generate Key
  1. If usages contains a value which is not one of "deriveKey" or "deriveBits", then throw a SyntaxError.

  2. Generate a Diffie-Hellman key pair, as defined in Section 7 of [PKCS #3], with prime, p, and base, g, as specified in the prime and generator properties of normalizedAlgorithm, respectively.

  3. If performing the operation results in an error, then throw an OperationError.

  4. Let algorithm be a new DhKeyAlgorithm object.

  5. Set the name member of algorithm to "DH".

  6. Set the prime attribute of algorithm to equal the prime member of normalizedAlgorithm.

  7. Set the generator attribute of algorithm to equal the generator member of normalizedAlgorithm.

  8. Let publicKey be a new CryptoKey object representing the public key of the generated key pair.

  9. Set the [[type]] internal slot of publicKey to "public"

  10. Set the [[algorithm]] internal slot of publicKey to algorithm.

  11. Set the [[extractable]] internal slot of publicKey to true.

  12. Set the [[usages]] internal slot of publicKey to be the empty list.

  13. Let privateKey be a new CryptoKey object representing the private key of the generated key pair.

  14. Set the [[type]] internal slot of privateKey to "private"

  15. Set the [[algorithm]] internal slot of privateKey to algorithm.

  16. Set the [[extractable]] internal slot of privateKey to extractable.

  17. Set the [[usages]] internal slot of privateKey to be usages.

  18. Let result be a new CryptoKeyPair dictionary.

  19. Set the publicKey attribute of result to be publicKey.

  20. Set the privateKey attribute of result to be privateKey.

  21. Return the result of converting result to an ECMAScript Object, as defined by [WebIDL].

Derive Bits
  1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

  2. Let publicKey be the public member of normalizedAlgorithm.

  3. If the name attribute of the [[algorithm]] internal slot of publicKey is not "DH", then throw a DataError.

  4. If the [[type]] internal slot of publicKey is not "public", then throw a DataError.

  5. If the prime attribute of the [[algorithm]] internal slot of publicKey is not equal to the prime attribute of the [[algorithm]] internal slot of key, then throw a DataError.

  6. If the generator attribute of the [[algorithm]] internal slot of publicKey is not equal to the generator attribute of the [[algorithm]] internal slot of key, then throw a DataError.

  7. Perform the Diffie-Hellman Phase II algorithm as specified in Section 8 of [PKCS #3] with key as the DH private value x and the Diffie-Hellman public value represented by the [[handle]] internal slot of the public member of normalizedAlgorithm as the other's public value PV'.

    If performing the operation results in an error:
    throw an OperationError.
    Otherwise:
    Let secret be the output of the DH Phase II, SK.
  8. If the length of secret in bits is less than length:
    throw an OperationError.
    Otherwise:
    Return the first length bits of secret.
Import Key
If format is "raw":
Editorial note

Raw import of private values is presently not supported.

  1. If usages is not empty then throw a SyntaxError.

  2. If extractable is false, then throw a SyntaxError.

  3. Let PV be the integer which results from interpreting the octets of keyData as an unsigned big integer with most significant octet first.

  4. Let key be a new CryptoKey object representing a Diffie-Hellman public key with public value PV and with prime, p and base, g equal to the prime and generator properties of normalizedAlgorithm respectively.

  5. Set the [[type]] internal slot of key to "public".

  6. Let algorithm be a new DhKeyAlgorithm.

  7. Set the name attribute of algorithm to "DH".

  8. Set the prime attribute of algorithm to equal the prime member of normalizedAlgorithm.

  9. Set the generator attribute of algorithm to equal the generator member of normalizedAlgorithm.

  10. Set the [[algorithm]] internal slot of key to algorithm.

  11. Return key.

If format is "spki":
  1. If usages is not empty then throw a SyntaxError.

  2. Let spki be the result of running the parse a subjectPublicKeyInfo algorithm over keyData.

  3. If an error occurred while parsing, then throw a DataError.

  4. If the algorithm object identifier field of the algorithm AlgorithmIdentifier field of spki is not equivalent to the dhKeyAgreement OID defined in Section 9 of [PKCS #3], then throw a DataError.

  5. If the parameters field of the algorithm AlgorithmIdentifier field of spki is absent, then throw a DataError.

  6. Let params be the parameters field of the algorithm AlgorithmIdentifier field of spki.

  7. If params is not an instance of the DHParameter ASN.1 type defined in Section 9 of PKCS #3, then throw a DataError.

  8. Let key be a new CryptoKey object representing the Diffie-Hellman public key obtained by parsing the subjectPublicKey field of spki as an ASN.1 INTEGER.

  9. Set the [[type]] internal slot of key to "public".

  10. Let algorithm be a new DhKeyAlgorithm.

  11. Set the name member of algorithm to "DH".

  12. Set the prime attribute of algorithm to a new BigInteger equal to the octet string encoding of the prime field of params.

  13. Set the generator attribute of algorithm to a new BigInteger equal to the octet string encoding of the base field of params.

  14. Set the [[algorithm]] internal slot of key to algorithm.

  15. Return key.

If format is "pkcs8":
  1. If usages contains a value which is not one of "deriveKey" or "deriveBits", then throw a SyntaxError.

  2. Let privateKeyInfo be the result of running the parse a privateKeyInfo algorithm over keyData.

  3. If an error occurred while parsing, then throw a DataError.

  4. If the algorithm object identifier field of the algorithm AlgorithmIdentifier field of privateKeyInfo is not equivalent to the dhKeyAgreement OID defined in Section 9 of [PKCS #3], then throw a DataError.

  5. If the parameters field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo is absent, then throw a DataError.

  6. Let params be the parameters field of the privateKeyAlgorithm PrivateKeyAlgorithmIdentifier field of privateKeyInfo.

  7. If params is not an instance of the DHParameter ASN.1 type defined in Section 9 of PKCS #3, then throw a DataError.

  8. Let key be a new CryptoKey object representing the Diffie-Hellman private key obtained by parsing the privateKey field of privateKeyInfo as an ASN.1 INTEGER.
  9. Set the [[type]] internal slot of key to "private".

  10. Let algorithm be a new DhKeyAlgorithm.

  11. Set the name member of algorithm to "DH".

  12. Set the prime attribute of algorithm to a new BigInteger equal to the octet string encoding of the prime field of params.

  13. Set the generator attribute of algorithm to a new BigInteger equal to the octet string encoding of the base field of params.

  14. Set the [[algorithm]] internal slot of key to algorithm.

  15. Return key.

Otherwise:
throw a NotSupportedError.
Export Key
  1. If the underlying cryptographic key material represented by the [[handle]] internal slot of key cannot be accessed, then throw an OperationError.

  2. If format is "raw":
    1. If the [[type]] internal slot of key is "public":
      Let data be the Public Value, PV, associated with key as specified in Section 7 of [PKCS #3].
      If the [[type]] internal slot of key is "private":
      Let data be the octet string that represents the private value x associated with key as a big integer, most significant octet first.
    2. Let result be a new ArrayBuffer containing data.

    If format is "spki":
    1. If the [[type]] internal slot of key is not "public", then throw an InvalidAccessError.

    2. Let data be an instance of the subjectPublicKeyInfo ASN.1 structure defined in RFC 5280 with the following properties:

      • Set the algorithmIdentifier field to an AlgorithmIdentifier ASN.1 structure with the following properties:

        • Set the algorithm field to the dhKeyAgreement OID defined in Section 9 of PKCS #3.

        • Set the parameters field to an instance of the DHParams ASN.1 structure defined in Section 9 of PKCS #3 with the following properties:

          • Set the prime field to an ASN.1 INTEGER that is equivalent to the prime attribute of the [[algorithm]] internal slot of key.

          • Set the base field to an ASN.1 INTEGER that is equivalent to the generator attribute of the [[algorithm]] internal slot of key.

      • Set the subjectPublicKey to an ASN.1 INTEGER that corresponds to the Diffie-Hellman public value represented by [[handle]] internal slot of key.

    3. Let result be a new ArrayBuffer containing data.

    If format is "pkcs8":
    1. If the [[type]] internal slot of key is not "private", then throw an InvalidAccessError.

    2. Let data be an instance of the privateKeyInfo ASN.1 structure defined in RFC 5280 with the following properties:

      • Set the privateKeyAlgorithm field to a PrivateKeyAlgorithmIdentifier ASN.1 structure with the following properties:

        • Set the algorithm field to the dhKeyAgreement OID defined in Section 9 of PKCS #3.

        • Set the parameters field to an instance of the DHParams ASN.1 structure defined in Section 9 of PKCS #3 with the following properties:

          • Set the prime field to an ASN.1 INTEGER that is equivalent to the prime attribute of the [[algorithm]] internal slot of key.

          • Set the base field to an ASN.1 INTEGER that is equivalent to the generator attribute of the [[algorithm]] internal slot of key.

      • Set the privateKey field to an ASN.1 INTEGER that corresponds to the Diffie-Hellman private value represented by [[handle]] internal slot of key.

    3. Let result be a new ArrayBuffer containing data.

    Otherwise:
    throw a NotSupportedError.
  3. Return result.

33. SHA

33.1. Description

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

33.2. Registration

The following algorithms are added as recognized algorithm names:

"SHA-1"
The SHA-1 algorithm as specified in Section 6.1
"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

33.3. Operations

Digest
  1. If the name member of normalizedAlgorithm is a cases-sensitive string match for "SHA-1":
    Let result be the result of performing the SHA-1 hash function defined in Section 6.1 of [FIPS PUB 180-4] using message as the input message, M.
    If the name member of normalizedAlgorithm is a cases-sensitive string match for "SHA-256":
    Let result be the result of performing the SHA-256 hash function defined in Section 6.2 of [FIPS PUB 180-4] using message as the input message, M.
    If the name member of normalizedAlgorithm is a cases-sensitive string match for "SHA-384":
    Let result be the result of performing the SHA-384 hash function defined in Section 6.5 of [FIPS PUB 180-4] using message as the input message, M.
    If the name member of normalizedAlgorithm is a cases-sensitive string match for "SHA-512":
    Let result be the result of performing the SHA-1 hash function defined in Section 6.4 of [FIPS PUB 180-4] using message as the input message, M.
  2. If performing the operation results in an error, then throw an OperationError.

  3. Return a new ArrayBuffer containing result.

34. Concat KDF

34.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 SP800-56A] using the SHA hash functions defined in this specification.

Other specifications may specify the use of additional hash algorithms with Concat KDF. Such specifications must define digest operations for the additional hash algorithms and key import steps for Concat KDF.

34.2. Registration

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

Operation Parameters Result
deriveBits ConcatParams Octet string
Import key None CryptoKey
Get key length None Integer or null

34.3. ConcatParams dictionary

IDL

dictionary ConcatParams : Algorithm {
// The digest method to use to derive the keying material.
HashAlgorithmIdentifier 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.
required BufferSource algorithmId;
// A bit string that corresponds to the PartyUInfo field of the OtherInfo parameter.
required BufferSource partyUInfo;
// A bit string that corresponds to the PartyVInfo field of the OtherInfo parameter.
required BufferSource partyVInfo;
// An optional bit string that corresponds to the SuppPubInfo field of the OtherInfo parameter.
BufferSource publicInfo;
// An optional bit string that corresponds to the SuppPrivInfo field of the OtherInfo parameter.
BufferSource privateInfo;
};
          

34.4. Operations

Derive Bits
  1. Let secret be the result of performing the Concatenation Key Derivation Function defined in Section 5.8.1 of [SP800-56A] with length as keydatalen, the hash function identified by the hash member of normalizedAlgorithm as H, the algorithmId member of normalizedAlgorithm as AlgorithmID, the partyUInfo member of normalizedAlgorithm as PartyUInfo, the partyVInfo member of normalizedAlgorithm as PartyVInfo, the publicInfo member of normalizedAlgorithm, if present, as SuppPubInfo and the privateInfo member of normalizedAlgorithm, if present, as SuppPrivInfo.

  2. If the operation fails, then throw an OperationError.

  3. Return secret

Import key
  1. Let keyData be the key data to be imported.

  2. Perform any key import steps defined by other applicable specifications, passing keyData and obtaining result.

    If result is a CryptoKey object

    Return result.

    If result is an error with a name that is not NotSupportedError

    throw result.

  3. If format is "raw":
    1. If usages contains a value that is not "deriveKey" or "deriveBits", then throw a SyntaxError.

    2. Let key be a new CryptoKey object representing the key data provided in keyData.

    3. Set the [[type]] internal slot of key to "secret".

    4. Let algorithm be a new KeyAlgorithm object.

    5. Set the name attribute of algorithm to "CONCAT".

    6. Set the [[algorithm]] internal slot of key to algorithm.

    7. Return key.

    Otherwise:
    throw a NotSupportedError.
Get length
  1. Return null.

35. HKDF-CTR

35.1. Description

This section is non-normative.

The "HKDF-CTR" algorithm identifier is used to perform key derivation using the extraction-then-expansion approach described in [NIST SP800-56C], using HMAC in counter mode, and using the SHA hash functions defined in this specification as described in Section 5.1 of [NIST SP800-108].

Other specifications may specify the use of additional hash algorithms with HKDF. Such specifications must define the digest operation for the additional hash algorithms.

35.2. Registration

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

Operation Parameters Result
deriveBits HkdfCtrParams ArrayBuffer
Import key None CryptoKey
Get key length None Integer or null

35.3. HkdfCtrParams dictionary

IDL

dictionary HkdfCtrParams : Algorithm {
// The algorithm to use with HMAC (e.g.: SHA-256)
required HashAlgorithmIdentifier hash;
// A bit string that corresponds to the label that identifies the purpose for the derived keying material.
required BufferSource label;
// A bit string that corresponds to the context of the key derivation, as described in Section 5 of [NIST SP800-108]
required BufferSource 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 behavior be of a user agent that does not support explicit salt values (is it conforming or non-conforming?)

35.4. Operations

Derive Bits
  1. If length is null, then throw a TypeError.

  2. If the hash member of normalizedAlgorithm does not describe a recognized algorithm that supports the digest operation, then throw a NotSupportedError

  3. Let extractKey be a key equal to n zero bits where n is the size of the output of the hash function described by the hash member of normalizedAlgorithm.

  4. Let prf be the MAC Generation function described in Section 4 of [FIPS PUB 198-1] using the hash function described by the hash member of normalizedAlgorithm.

  5. Let keyDerivationKey be the result of performing prf using extractKey as the key and the secret represented by [[handle]] internal slot of key as the message.

  6. Let result be the result of performing the KDF in counter mode operation described in Section 5.1 of [NIST SP800-108] using:

    • prf as the Pseudo-Random Function, PRF,

    • keyDerivationKey as the Key derivation key, KI,

    • the contents of the label member of normalizedAlgorithm as Label,

    • the contents of the context member of normalizedAlgorithm as Context,

    • length as the value of L,

    • 32 as the value of r, and

    • the 32-bit little-endian binary encoding of length as the encoded length value [L]2.

  7. If the key derivation operation fails, then throw an OperationError.

  8. Return result.

Import key
  1. Let keyData be the key data to be imported.

  2. If format is "raw":
    1. If usages contains a value that is not "deriveKey" or "deriveBits", then throw a SyntaxError.

    2. Let key be a new CryptoKey object representing the key data provided in keyData.

    3. Set the [[type]] internal slot of key to "secret".

    4. Let algorithm be a new KeyAlgorithm object.

    5. Set the name attribute of algorithm to "HKDF-CTR".

    6. Set the [[algorithm]] internal slot of key to algorithm.

    7. Return key.

    Otherwise:
    throw a NotSupportedError.
Get length
  1. Return null.

36. PBKDF2

36.1. Description

This section is non-normative.

The "PBKDF2" algorithm identifier is used to perform key derivation using the PKCS#5 password-based key derivation function version 2.0, as defined in [RFC2898] using HMAC as the pseudo-random function, using the SHA hash functions defined in this specification.

Other specifications may specify the use of additional hash algorithms with PBKDF2. Such specifications must define the digest operation for the additional hash algorithms.

36.2. Registration

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

Operation Parameters Result
generateKey None CryptoKey
deriveBits Pbkdf2Params ArrayBuffer
importKey None CryptoKey
Get key length None Length or null

36.3. Pbkdf2Params dictionary

IDL

dictionary Pbkdf2Params : Algorithm {
required BufferSource salt;
[EnforceRange] required unsigned long iterations;
required HashAlgorithmIdentifier hash;
};
          

36.4. Operations

Derive bits
  1. If length is null or is not a multiple of 8, then throw an OperationError.

  2. If the hash member of normalizedAlgorithm does not describe a recognized algorithm that supports the digest operation, then throw a NotSupportedError

  3. Let prf be the MAC Generation function described in Section 4 of [FIPS PUB 198-1] using the hash function described by the hash member of normalizedAlgorithm.

  4. Let result be the result of performing the PBKDF2 operation defined in Section 5.2 of [RFC2898] using prf as the pseudo-random function, PRF, the password represented by [[handle]] internal slot of key as the password, P, the contents of the salt attribute of normalizedAlgorithm as the salt, S, the value of the iterations attribute of normalizedAlgorithm as the iteration count, c, and length divided by 8 as the intended key length, dkLen.

  5. If the key derivation operation fails, then throw an OperationError.

  6. Return result

Generate key
  1. If usages contains a value that is not "deriveKey" or "deriveBits", then throw a SyntaxError.

  2. If extractable is true, then throw a SyntaxError.

  3. Generate a new password by prompting the user.

  4. Let key be a new CryptoKey object representing the provided password as a series of bytes encoded using UTF-8.

  5. Set the [[type]] internal slot of key to "secret".

  6. Let algorithm be a new KeyAlgorithm object.

  7. Set the name attribute of algorithm to "PBKDF2".

  8. Set the [[algorithm]] internal slot of key to algorithm.

  9. Set the [[extractable]] internal slot of key to extractable.

  10. Set the [[usages]] internal slot of key to the normalized value of usages.

  11. Return key.

Import key
  1. If format is not "raw", throw a NotSupportedError

  2. If usages contains a value that is not "deriveKey" or "deriveBits", then throw a SyntaxError.

  3. Let key be a new CryptoKey object representing keyData.

  4. Set the [[type]] internal slot of key to "secret".

  5. Let algorithm be a new KeyAlgorithm object.

  6. Set the name attribute of algorithm to "PBKDF2".

  7. Set the [[algorithm]] internal slot of key to algorithm.

  8. Return key.

Get length
  1. Return null.

37. JavaScript Example Code

37.1. Generate a signing key pair, sign some data

ECMAScript

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

var algorithmSign = {
  name: "RSASSA-PKCS1-v1_5"
};

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

    return window.crypto.subtle.sign(algorithmSign, key.privateKey, [dataPart1, dataPar2]);
  },
  console.error.bind(console, "Unable to generate a key")
).then(
  console.log.bind(console, "The signature is: "),
  console.error.bind(console, "Unable to sign")
);
        

37.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 key generator to produce a one-time-use AES key to encrypt some data
window.crypto.subtle.generateKey(aesAlgorithmKeyGen, false, ["encrypt"]).then(
  function(aesKey) {
    return window.crypto.subtle.encrypt(aesAlgorithmEncrypt, aesKey, [ clearDataArrayBufferView ]);
  }
).then(console.log.bind(console, "The ciphertext is: "),
       console.error.bind(console, "Unable to encrypt"));
        

38. IANA Considerations

38.1. JSON Web Signature and Encryption Algorithms Registration

This section registers the following algorithm identifiers in the IANA JSON Web Signature and Encryption Algorithms Registry for use with JSON Web Key. Note that the 'Implementation Requirements' field in the template refers to use with JSON Web Signature and JSON Web Encryption specifically, in which case use of unauthenticated encryption is prohibited.

  • Algorithm Name: "RS1"
  • Algorithm Description: RSASSA-PKCS1-v1_5 with SHA-1
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "RSA-OAEP-384"
  • Algorithm Description: RSA-OAEP using SHA-384 and MGF1 with SHA-384
  • Algorithm Usage Location(s): "alg"
  • JOSE Implementation Requirements: Optional+
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "RSA-OAEP-512"
  • Algorithm Description: RSA-OAEP using SHA-512 and MGF1 with SHA-512
  • Algorithm Usage Location(s): "alg"
  • JOSE Implementation Requirements: Optional+
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "A128CBC"
  • Algorithm Description: AES CBC using 128 bit key
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "A192CBC"
  • Algorithm Description: AES CBC using 192 bit key
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "A256CBC"
  • Algorithm Description: AES CBC using 256 bit key
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "A128CTR"
  • Algorithm Description: AES CTR using 128 bit key
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "A192CTR"
  • Algorithm Description: AES CTR using 192 bit key
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "A256CTR"
  • Algorithm Description: AES CTR using 256 bit key
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "A128CMAC"
  • Algorithm Description: AES CMAC using 128 bit key
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "A192CMAC"
  • Algorithm Description: AES CMAC using 192 bit key
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "A256CMAC"
  • Algorithm Description: AES CMAC using 256 bit key
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "A128CFB8"
  • Algorithm Description: AES CFB-8 using 128 bit key
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "A192CFB8"
  • Algorithm Description: AES CFB-8 using 192 bit key
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "A256CFB8"
  • Algorithm Description: AES CFB-8 using 256 bit key
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]
  • Algorithm Name: "HS1"
  • Algorithm Description: HMAC using SHA-1
  • Algorithm Usage Location(s): "JWK"
  • JOSE Implementation Requirements: Prohibited
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document ]]

38.2. JSON Web Key Parameters Registration

  • Parameter Name: "ext"
  • Parameter Description: Extractable
  • Used with "kty" Value(s): *
  • Parameter Information Class: Public
  • Change Controller: W3C Web Cryptography Working Group
  • Specification Document(s): [[ This Document]]

39. Acknowledgements

The editors would like to thank Adam Barth, Alex Russell, Ali Asad, Arun Ranganathan, Brian Smith, Brian Warner, Channy Yun, Eric Roman, Glenn Adams, Jim Schaad, Kai Engert, Mark Watson, Michael Hutchinson, Michael B. Jones, 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.

40. References

40.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.
ECMA262
ECMAScript 5th Edition, A. Wirfs-Brock, P. Lakshman et al.
FIPS 180-4
FIPS PUB 180-4: Secure Hash Standard, NIST.
FIPS 198-1
The Keyed-Hash Message Authentication Code (HMAC) , July 2008, NIST.
HTML
HTML5: A vocabulary and associated APIs for HTML and XHTML (work in progress), I. Hickson. W3C.
ITU-T Recommendation X.690 (11/08)
Information technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER) , ITU-T.
JSON Web Key
JSON Web Key (work in progress), M. Jones, Microsoft.
JSON Web Algorithms
JSON Web Algorithms (work in progress), M. Jones, Microsoft.
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-38D
NIST Special Publication 800-38D: Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC, November 2007, 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.
PKCS3
PKCS #3: Diffie-Hellman Key-Agreement Standard, RSA Laboratories.
RFC 2119
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF.
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 3279
Algorithms and Identifiers for the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile, W. Polk, R. Housley, L. Bassham. IETF.
RFC3394
Advanced Encryption Standard (AES) Key Wrap Algorithm, J. Schaad, R. Housley, IETF.
RFC 3447
Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1, J. Jonsson, B. Kaliski. IETF.
RFC 5208
Public-Key Cryptography Standards (PKCS) #8: Private-Key Information Syntax Specification Version 1.2, B. Kaliski. IETF.
RFC 5280
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.
RFC 5480
Elliptic Curve Cryptography Subject Public Key Information, S. Turner, D. Brown, K. Yiu, R. Housley, T. Polk. IETF.
RFC 5915
Elliptic Curve Private Key Structure , S. Turner, D. Brown. IETF.
Web IDL (Second Edition)
Web IDL (Second Edition), 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.

40.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.
Indexed Database API
Indexed Database API, N. Mehta, J. Sicking, E. Graff, A. Popescu, J. Orlow, J. Bell. W3C.
PKCS11
PKCS #11: Cryptographic Token Interface Standard, RSA Laboratories.
RFC 4055
Additional Algorithms and Identifiers for RSA Cryptography for use in the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile, J. Schaad, B. Kaliski, R. Housley. IETF.
RFC 5756
Updates for RSAES-OAEP and RSASSA-PSS Algorithm Parameters, S. Turner, D. Brown, K. Yiu, R. Housley, T. Polk. IETF.
RFC 5869
HMAC-based Extract-and-Expand Key Derivation Function (HKDF), H. Krawczyk, P. Eronen. IETF.
RFC 5958
Asymmetric Key Packages, S. Turner. IETF.
StreamsAPI
Streams API , F. Moussa. W3C.

A. Mapping between JSON Web Key / JSON Web Algorithm

The following section is non-normative. Refer to algorithm-specific sections for the normative requirements of importing and exporting JWK.

A.1. Algorithm mappings

JSON Web Key AlgorithmIdentifier
ECMAScript

{ kty: "RSA",
  alg: "RS1" }
ECMAScript

{ name: "RSASSA-PKCS1-v1_5",
  hash: { name: "SHA-1" }
}
ECMAScript

{ kty: "RSA",
  alg: "RS256" }
ECMAScript

{ name: "RSASSA-PKCS1-v1_5",
  hash: { name: "SHA-256" }
}
ECMAScript

{ kty: "RSA",
  alg: "RS384" }
ECMAScript

{ name: "RSASSA-PKCS1-v1_5",
  hash: { name: "SHA-384" }
}
ECMAScript

{ kty: "RSA",
  alg: "RS512" }
ECMAScript

{ name: "RSASSA-PKCS1-v1_5",
  hash: { name: "SHA-512" }
}
ECMAScript

{ kty: "RSA",
  alg: "PS256" }
ECMAScript

{ name: "RSA-PSS",
  hash: { name: "SHA-256" }
}
ECMAScript

{ kty: "RSA",
  alg: "PS384" }
ECMAScript

{ name: "RSA-PSS",
  hash: { name: "SHA-384" }
}
ECMAScript

{ kty: "RSA",
  alg: "PS512" }
ECMAScript

{ name: "RSA-PSS",
  hash: { name: "SHA-512" }
}
ECMAScript

{ kty: "RSA",
  alg: "RSA-OAEP" }
ECMAScript

{ name: "RSA-OAEP",
  hash: { name: "SHA-1" }
}
ECMAScript

{ kty: "RSA",
  alg: "RSA-OAEP-256" }
ECMAScript

{ name: "RSA-OAEP",
  hash: { name: "SHA-256" }
}
ECMAScript

{ kty: "RSA",
  alg: "RSA-OAEP-384" }
ECMAScript

{ name: "RSA-OAEP",
  hash: { name: "SHA-384" }
}
ECMAScript

{ kty: "RSA",
  alg: "RSA-OAEP-512" }
ECMAScript

{ name: "RSA-OAEP",
  hash: { name: "SHA-512" }
}
ECMAScript

{ kty: "EC",
  alg: "ES256" }
ECMAScript

{ name: "ECDSA",
  namedCurve: "P-256"
  hash: { name: "SHA-256" }
}
ECMAScript

{ kty: "EC",
  alg: "ES384" }
ECMAScript

{ name: "ECDSA",
  namedCurve: "P-384"
  hash: { name: "SHA-384" }
}
ECMAScript

{ kty: "EC",
  alg: "ES512" }
ECMAScript

{ name: "ECDSA",
  namedCurve: "P-521"
  hash: { name: "SHA-512" }
}
ECMAScript

{ kty: "oct",
  alg: "A128CTR" }
ECMAScript

{ name: "AES-CTR",
  length: 128 }
ECMAScript

{ kty: "oct",
  alg: "A192CTR" }
ECMAScript

{ name: "AES-CTR",
  length: 192 }
ECMAScript

{ kty: "oct",
  alg: "A256CTR" }
ECMAScript

{ name: "AES-CTR",
  length: 256 }
ECMAScript

{ kty: "oct",
  alg: "A128CBC" }
ECMAScript

{ name: "AES-CBC",
  length: 128 }
ECMAScript

{ kty: "oct",
  alg: "A192CBC" }
ECMAScript

{ name: "AES-CBC",
  length: 192 }
ECMAScript

{ kty: "oct",
  alg: "A256CBC" }
ECMAScript

{ name: "AES-CBC",
  length: 256 }
ECMAScript

{ kty: "oct",
  alg: "A128KW" }
ECMAScript

{ name: "AES-KW",
  length: 128 }
ECMAScript

{ kty: "oct",
  alg: "A192KW" }
ECMAScript

{ name: "AES-KW",
  length: 192 }
ECMAScript

{ kty: "oct",
  alg: "A256KW" }
ECMAScript

{ name: "AES-KW",
  length: 256 }
ECMAScript

{ kty: "oct",
  alg: "A128GCM" }
ECMAScript

{ name: "AES-GCM",
  length: 128 }
ECMAScript

{ kty: "oct",
  alg: "A192GCM" }
ECMAScript

{ name: "AES-GCM",
  length: 192 }
ECMAScript

{ kty: "oct",
  alg: "A256GCM" }
ECMAScript

{ name: "AES-GCM",
  length: 256 }
ECMAScript

{ kty: "oct",
  alg: "A128GCMKW" }
ECMAScript

{ name: "AES-GCM",
  length: 128 }
ECMAScript

{ kty: "oct",
  alg: "A192GCMKW" }
ECMAScript

{ name: "AES-GCM",
  length: 192 }
ECMAScript

{ kty: "oct",
  alg: "A256GCMKW" }
ECMAScript

{ name: "AES-GCM",
  length: 256 }
ECMAScript

{ kty: "oct",
  alg: "A128CMAC" }
ECMAScript

{ name: "AES-CMAC",
  length: 128 }
ECMAScript

{ kty: "oct",
  alg: "A192CMAC" }
ECMAScript

{ name: "AES-CMAC",
  length: 192 }
ECMAScript

{ kty: "oct",
  alg: "A256CMAC" }
ECMAScript

{ name: "AES-CMAC",
  length: 256 }
ECMAScript

{ kty: "oct",
  alg: "A128CFB8" }
ECMAScript

{ name: "AES-CFB-8",
  length: 128 }
ECMAScript

{ kty: "oct",
  alg: "A192CFB8" }
ECMAScript

{ name: "AES-CFB-8",
  length: 192 }
ECMAScript

{ kty: "oct",
  alg: "A256CFB8" }
ECMAScript

{ name: "AES-CFB-8",
  length: 256 }
ECMAScript

{ kty: "oct",
  alg: "HS1" }
ECMAScript

{ name: "HMAC",
  hash: { name: "SHA-1" }
}
ECMAScript

{ kty: "oct",
  alg: "HS256" }
ECMAScript

{ name: "HMAC",
  hash: { name: "SHA-256" }
}
ECMAScript

{ kty: "oct",
  alg: "HS384" }
ECMAScript

{ name: "HMAC",
  hash: { name: "SHA-384" }
}
ECMAScript

{ kty: "oct",
  alg: "HS512" }
ECMAScript

{ name: "HMAC",
  hash: "SHA-512" }
Editorial note

Should the following be specified.

  • RSASSA-PKCS1-v1_5 with SHA-1

  • RSA-PSS with SHA-1

  • ECDSA with SHA-1

  • ECDSA where the curve (P-256, P-384, P-521) is not aligned with the hash (SHA-256, SHA-384, SHA-512)

A.2. Usage mapping

JWK use value KeyUsages
enc ["encrypt", "decrypt", "wrapKey", "unwrapKey"]
sig ["sign","verify"]

B. Mapping between Algorithm and SubjectPublicKeyInfo

The following section is non-normative. Refer to algorithm-specific sections for the normative requirements of importing and exporting SPKI.

Algorithm OID subjectPublicKey ASN.1 structure AlgorithmIdentifier Reference
rsaEncryption (1.2.840.113549.1.1.1) RSAPublicKey "RSASSA-PKCS1-v1_5", "RSA-PSS", or "RSA-OAEP" RFC 3279, RFC 4055, RFC 5756
id-RSASSA-PSS (1.2.840.113549.1.1.10) RSAPublicKey "RSA-PSS" RFC 4055, RFC 5756
id-RSAES-OAEP (1.2.840.113549.1.1.7) RSAPublicKey "RSA-OAEP" RFC 4055, RFC 5756
id-ecPublicKey (1.2.840.10045.2.1) ECPoint "ECDH" or "ECDSA" RFC 5480
id-ecDH (1.3.132.112) ECPoint "ECDH" RFC 5480
id-dsa (1.2.840.10040.4.1) DSAPublicKey "DSA" RFC 3279
dhKeyAgreement (1.2.840.113549.1.3.1) INTEGER "DH" PKCS #3
Editorial note

The handling of "id-RSASSA-PSS" and "id-RSAES-OAEP" are tricky. RFC 5756 recommends implementations should not include parameters when PSS is used with a subjectPublicKeyInfo, and MUST NOT include parameters when OAEP is used. However, when OAEP is used as part of a key transport (as an AlgorithmIdentifier), implementations MUST include the parameters.

The natural conflict is in deciding when a key is being exported as part of a subjectPublicKeyInfo (which is what "spki" implies) and when it's being used as an algorithmIdentifier for transport.

C. Mapping between Algorithm and PKCS#8 PrivateKeyInfo

The following section is non-normative. Refer to algorithm-specific sections for the normative requirements of importing and exporting PKCS#8 PrivateKeyInfo.

privateKeyAlgorithm privateKey format AlgorithmIdentifier Reference
rsaEncryption (1.2.840.113549.1.1.1) RSAPrivateKey "RSASSA-PKCS1-v1_5", "RSA-PSS", or "RSA-OAEP" RFC 3447, RFC 5958
id-RSASSA-PSS (1.2.840.113549.1.1.10) RSAPrivateKey "RSA-PSS" RFC 3447, RFC 4055, RFC 5958
id-RSAES-OAEP (1.2.840.113549.1.1.7) RSAPrivateKey "RSA-OAEP" RFC 3447, RFC 4055, RFC 5958
id-ecPublicKey (1.2.840.10045.2.1) ECPrivateKey "ECDH" or "ECDSA" RFC 5480, RFC 5915, RFC 5958
id-ecDH (1.3.132.112) ECPrivateKey "ECDH" RFC 5480, RFC 5915, RFC 5958
id-dsa (1.2.840.10040.4.1) INTEGER "DSA" RFC 5958
dhKeyAgreement (1.2.840.113549.1.3.1) INTEGER "DH" PKCS #3
Editorial note

There does not appear to be a normative reference for a DH key being encoded as an INTEGER. Only RFC 5958 seems to mention this.