W3C First Public Working Draft
Copyright © 2025 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
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.
This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C standards and drafts index at https://www.w3.org/TR/.
This document was published by the Web Application Security Working Group as a First Public Working Draft using the Recommendation track.
Publication as a First Public Working Draft does not imply endorsement by W3C and its Members.
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 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.
This document is governed by the 03 November 2023 W3C Process Document.
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 set of methods
for performing common cryptographic operations. 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 and key import and export.
This section is non-normative.
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 prefer the richer user experience provided by authenticating within the application itself.
Using the Web Cryptography API, the 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.
This exchange could be further strengthened by binding the authentication to the TLS session over which the client is authenticating, by deriving a key based on properties of the underlying transport.
If a user does 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 choice.
A web application may wish to limit the viewership of documents that contain sensitive or personal information, even when these documents have been securely received, such as over TLS.
Using the Web Cryptography API, the application could do so by encrypting the documents with a secret key, and then wrapping that key with the public keys associated with the authorized viewers. When a user agent navigates to such a web application, the application would 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.
A web application may wish to permit users to protect the confidentiality of data and documents stored with remote service providers prior to uploading.
Using the Web Cryptography API, the application may have a user select a private or secret key, optionally derive an encryption key from the selected key, encrypt the document, and then upload the encrypted data to the service provider using existing APIs.
This use case is similar to the Protected Document Exchange use case, with viewership of the document limited to the user themself.
A web application may wish to accept electronic signatures on documents, in lieu of requiring physical signatures.
Using the Web Cryptography API, the application may direct the user to select a key, which may have been pre-provisioned out-of-band, or generated specifically for the web application. Using this key, the application may perform a signing operation over some data, as proof that the user accepts the document.
A web application may wish to cache data locally, while ensuring that this data cannot be modified in an offline attack.
Using the Web Cryptography API, the application may use a public key contained within the application to verify the contents of the data cache. Previously, when data was added to the cache, it would have been signed by the server with the corresponding private key. By validating the signature when restoring data from the cache, the client ensures that the cached data has not been tampered with.
A web application may wish to employ message layer security using schemes such as off-the-record (OTR) messaging, even when these messages have been securely received, such as over TLS.
The Web Cryptography API enables OTR and similar message signing schemes, by allowing key agreement to be performed. 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.
A web application may wish to interact with the structures and message formats defined by the IETF JavaScript Object Signing and Encryption (JOSE) Working Group.
Using the Web Cryptography API, the application may read and import keys encoded in the JSON key format (JWK), validate messages that have been integrity protected using digital signatures or MACs (JWS), or decrypt messages that have been encrypted (JWE).
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 key words MUST, REQUIRED, and SHALL in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
The following conformance classes are defined by this specification:
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.
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 Web Cryptography Working Group are listed in the table below.
Specification | Reference |
This section is non-normative.
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.
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 behaviors of individual algorithms, if implemented.
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.
This section is non-normative.
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.
This specification does not explicitly provide any new storage mechanisms for
CryptoKey
objects. Instead, by defining
serialization and deserialization steps
for CryptoKey
objects, any existing or future web storage mechanisms that support
storing serializable objects can be used to store CryptoKey
objects.
In practice, it is expected that most authors will make use of the
Indexed Database API [INDEXEDDB], 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.
This section is non-normative.
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.
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.
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.
This section is non-normative.
randomUUID
as user ID
randomUUID
is useful for generating user
IDs, but does not directly give any ability to generate global
identifiers.
This specification relies on underlying specifications.
A conforming user agent MUST support at
least the subset of the functionality defined in DOM that this specification relies
upon; in particular, it MUST support Promise
s and
DOMException
.
[DOM]
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 serializable objects.
[HTML]
A conforming user agent MUST be a conforming implementation of the IDL fragments in this specification, as described in the Web IDL specification. [WebIDL]
The terms
ArrayBuffer
,
ArrayBufferView
, and
serializable objects,
are defined by the HTML specification [HTML].
The terms DOMString
and
BufferSource
are defined in [WEBIDL].
The term byte sequence is defined in [Infra].
The length in bits of a byte sequence is its length multiplied by 8.
A byte sequence containing a bit sequence b is the byte sequence obtained by first appending zero or more bits of value zero to b such that the length of the resulting bit sequence is minimal and an integer multiple of 8 and then considering each consecutive sequence of 8 bits in that string as a byte.
When this specification says to convert a non-negative integer i to a byte sequence of length n, where n * 8 is greater than the logarithm to base 2 of i, the user agent must first calculate the binary representation of i, most significant bit first, prefix this with sufficient zero bits to form a bit sequence of length n * 8, and then return the byte sequence formed by considering each consecutive sequence of 8 bits in that bit sequence as a byte.
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:
Let data be a sequence of bytes to be parsed.
Let structure be the ASN.1 structure to be parsed.
Let exactData be an optional boolean value. If it is not supplied,
let it be initialized to true
.
Parse data according to the Distinguished Encoding Rules of [X690], using structure as the ASN.1 structure to be decoded.
If exactData was specified, and all of the bytes of data were
not consumed during the parsing phase, then
throw a
DataError
.
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 [RFC5280],
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
[RFC5208], and exactData set to true
.
When this specification says to parse a JWK, the user agent must run the following steps:
Let data be the sequence of bytes to be parsed.
Let json be the Unicode string that results from interpreting data according to UTF-8.
Convert json to UTF-16.
Let result be the object literal that results from executing the
JSON.parse
internal function in the context of a new global object,
with text
argument set to a JavaScript String containing json.
Let key be the result of converting result to the IDL dictionary
type of JsonWebKey
.
If the kty
field of key is not defined, then throw a DataError
.
Return key.
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:
The Crypto
interface represents an interface to
general purpose cryptographic functionality including a
cryptographically strong pseudo-random number generator seeded with truly random values.
WebIDLpartial interface mixin WindowOrWorkerGlobalScope {
[SameObject] readonly attribute Crypto
crypto
;
};
[Exposed=(Window,Worker)]
interface Crypto
{
[SecureContext] readonly attribute SubtleCrypto
subtle
;
ArrayBufferView getRandomValues
(ArrayBufferView array);
[SecureContext] DOMString randomUUID
();
};
The getRandomValues
method generates cryptographically strong random values. It must act as follows:
If array is not an Int8Array
, Uint8Array
, Uint8ClampedArray
,
Int16Array
, Uint16Array
, Int32Array
, Uint32Array
,
BigInt64Array
, or BigUint64Array
, then throw a
TypeMismatchError
and
terminate the algorithm.
Let byteLength be the byte length of array.
If byteLength is greater than 65536, throw a
QuotaExceededError
and
terminate the algorithm.
Let bytes be a byte sequence of length byteLength.
Fill bytes with cryptographically secure random bytes.
Write bytes into array.
Return array.
Do not generate keys using the getRandomValues
method. Use the
generateKey
method
instead.
The randomUUID
method generates a new version 4 UUID
and returns its namespace specific string representation
as described in section 3 of [RFC4122].
To generate a random UUID:
0100
.
10
.
Return the string concatenation of «
-
",
-
",
-
",
-
",
».
For the steps described in the algorithm to generate a random UUID,
the hexadecimal representation of a byte value is the
two-character string created by expressing value in hexadecimal using
ASCII lower hex digits, left-padded with "0
" to reach two
ASCII lower hex digits.
The subtle
attribute provides
an instance of the SubtleCrypto
interface which provides
low-level cryptographic primitives and algorithms.
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.
WebIDLtypedef (object or DOMString) AlgorithmIdentifier
;
typedef AlgorithmIdentifier
HashAlgorithmIdentifier
;
dictionary Algorithm
{
required DOMString name
;
};
Algorithm
Dictionary Membersname
The KeyAlgorithm
dictionary represents information about the contents of a given
CryptoKey
object.
WebIDLdictionary KeyAlgorithm
{
required DOMString name
;
};
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.
name
CryptoKey
The CryptoKey
object represents an opaque reference to keying material that is managed by
the user agent.
WebIDLenum KeyType
{ "public
", "private
", "secret
" };
enum KeyUsage
{ "encrypt
", "decrypt
", "sign
", "verify
", "deriveKey
", "deriveBits
", "wrapKey
", "unwrapKey
" };
[SecureContext,Exposed=(Window,Worker),Serializable]
interface CryptoKey
{
readonly attribute KeyType
type
;
readonly attribute boolean extractable
;
readonly attribute object algorithm
;
readonly attribute object usages
;
};
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, e.g. when performing a cryptographic operation.
KeyType
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
encrypt
,
decrypt
,
sign
,
verify
,
deriveKey
,
deriveBits
,
wrapKey
and
unwrapKey
.
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.
type
[[type]]
internal slot,
which contains the type of the underlying key.
extractable
[[extractable]]
internal
slot, which indicates whether or not the raw keying material may be exported by the
application.
algorithm
[[algorithm]]
internal slot.
usages
[[usages]]
internal slot,
which indicates which cryptographic operations are permissible to be used with this key.
CryptoKey
objects are serializable objects. Their serialization steps,
given value and serialized, are:
[[type]]
internal slot of value.
[[extractable]]
internal slot of value.
[[algorithm]]
internal slot of value.
[[usages]]
internal slot of value.
[[handle]]
internal slot of value.
Their deserialization steps, given serialized and value, are:
[[type]]
internal slot of value to serialized.[[Type]].
[[extractable]]
internal slot of value to serialized.[[Extractable]].
[[algorithm]]
internal slot of value to the
sub-deserialization of serialized.[[Algorithm]].
[[usages]]
internal slot of value to the
sub-deserialization of serialized.[[Usages]].
[[handle]]
internal slot of value to serialized.[[Handle]].
CryptoKey
object, it is important that the
object is not deserialized as a different type. This is normatively required by the
definition of the deserialization steps, but it merits specific attention, as
such deserialization may expose the contents of the key material, which in some
cases (such as when the [[extractable]]
internal slot is false) should not
be exposed to applications.
The SubtleCrypto
interface provides a set of
methods for dealing with low-level cryptographic primitives and algorithms.
WebIDLenum KeyFormat
{ "raw
", "spki
", "pkcs8
", "jwk
" };
[SecureContext,Exposed=(Window,Worker)]
interface SubtleCrypto
{
Promise<ArrayBuffer> encrypt
(
AlgorithmIdentifier
algorithm,
CryptoKey
key,
BufferSource data
);
Promise<ArrayBuffer> decrypt
(
AlgorithmIdentifier
algorithm,
CryptoKey
key,
BufferSource data
);
Promise<ArrayBuffer> sign
(
AlgorithmIdentifier
algorithm,
CryptoKey
key,
BufferSource data
);
Promise<boolean> verify
(
AlgorithmIdentifier
algorithm,
CryptoKey
key,
BufferSource signature,
BufferSource data
);
Promise<ArrayBuffer> digest
(
AlgorithmIdentifier
algorithm,
BufferSource data
);
Promise<(CryptoKey
or CryptoKeyPair
)> generateKey
(
AlgorithmIdentifier
algorithm,
boolean extractable,
sequence<KeyUsage
> keyUsages
);
Promise<CryptoKey
> deriveKey
(
AlgorithmIdentifier
algorithm,
CryptoKey
baseKey,
AlgorithmIdentifier
derivedKeyType,
boolean extractable,
sequence<KeyUsage
> keyUsages
);
Promise<ArrayBuffer> deriveBits
(
AlgorithmIdentifier
algorithm,
CryptoKey
baseKey,
optional unsigned long? length = null
);
Promise<CryptoKey
> importKey
(
KeyFormat
format,
(BufferSource or JsonWebKey
) keyData,
AlgorithmIdentifier
algorithm,
boolean extractable,
sequence<KeyUsage
> keyUsages
);
Promise<(ArrayBuffer or JsonWebKey
)> exportKey
(
KeyFormat
format,
CryptoKey
key
);
Promise<ArrayBuffer> wrapKey
(
KeyFormat
format,
CryptoKey
key,
CryptoKey
wrappingKey,
AlgorithmIdentifier
wrapAlgorithm
);
Promise<CryptoKey
> unwrapKey
(
KeyFormat
format,
BufferSource wrappedKey,
CryptoKey
unwrappingKey,
AlgorithmIdentifier
unwrapAlgorithm,
AlgorithmIdentifier
unwrappedKeyAlgorithm,
boolean extractable,
sequence<KeyUsage
> keyUsages
);
};
The SubtleCrypto
interface 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.
KeyFormat
raw
pkcs8
spki
jwk
JsonWebKey
dictionary encoded as a JavaScript objectSubtleCrypto
.
SubtleCrypto
,
neither between multiple calls, nor between calls and tasks
from other task sources.
This task source is merely used to queue a task to
resolve or reject the relevant promise whenever the
cryptographic operation is completed, in order to
prevent race conditions.
All errors are reported asynchronously by rejecting the returned Promise. This includes Web IDL type mapping errors.
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:
Let algorithm and key be the
algorithm
and key
parameters
passed to the encrypt
()
method,
respectively.
Let data be the result of
getting a copy of the bytes held by the data
parameter passed to the
encrypt
()
method.
Let normalizedAlgorithm be the result of
normalizing an algorithm, with
alg
set to algorithm and op
set to
"encrypt
".
If an error occurred, return a Promise rejected with normalizedAlgorithm.
Let realm be the relevant realm of this.
Let promise be a new Promise.
Return promise and perform the remaining steps in parallel.
If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.
If the name
member of
normalizedAlgorithm is not equal to the
name
attribute of the
[[algorithm]]
internal slot of
key then throw an InvalidAccessError
.
If the [[usages]]
internal slot of
key does not contain an entry that is "encrypt
", then throw an InvalidAccessError
.
Let ciphertext be the result of performing the encrypt operation specified by normalizedAlgorithm using algorithm and key and with data as plaintext.
Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.
Let result be the result of creating an ArrayBuffer
in realm, containing ciphertext.
Resolve promise with result.
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:
Let algorithm and key be the
algorithm
and key
parameters
passed to the decrypt
()
method,
respectively.
Let data be the result of
getting a copy of the bytes held by the data
parameter passed to the
decrypt
()
method.
Let normalizedAlgorithm be the result of
normalizing an algorithm, with
alg
set to algorithm and op
set to
"decrypt
".
If an error occurred, return a Promise rejected with normalizedAlgorithm.
Let realm be the relevant realm of this.
Let promise be a new Promise.
Return promise and perform the remaining steps in parallel.
If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.
If the name
member of
normalizedAlgorithm is not equal to the
name
attribute of the
[[algorithm]]
internal slot of
key then throw an InvalidAccessError
.
If the [[usages]]
internal slot of
key does not contain an entry that is "decrypt
", then throw an InvalidAccessError
.
Let plaintext be the result of performing the decrypt operation specified by normalizedAlgorithm using key and algorithm and with data as ciphertext.
Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.
Let result be the result of creating an ArrayBuffer
in realm, containing plaintext.
Resolve promise with result.
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:
Let algorithm and key be the
algorithm
and key
parameters
passed to the sign
()
method,
respectively.
Let data be the result of
getting a copy of the bytes held by the data
parameter passed to the
sign
()
method.
Let normalizedAlgorithm be the result of
normalizing an algorithm, with
alg
set to algorithm and op
set to
"sign
".
If an error occurred, return a Promise rejected with normalizedAlgorithm.
Let realm be the relevant realm of this.
Let promise be a new Promise.
Return promise and perform the remaining steps in parallel.
If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.
If the name
member of
normalizedAlgorithm is not equal to the
name
attribute of the
[[algorithm]]
internal slot of
key then throw an InvalidAccessError
.
If the [[usages]]
internal slot of
key does not contain an entry that is "sign
", then throw an InvalidAccessError
.
Let signature be the result of performing the sign operation specified by normalizedAlgorithm using key and algorithm and with data as message.
Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.
Let result be the result of creating an ArrayBuffer
in realm, containing signature.
Resolve promise with result.
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:
Let algorithm and key
be the algorithm
and key
parameters passed to the
verify
()
method, respectively.
Let signature be the result of
getting a copy of the bytes held by the signature
parameter passed to the
verify
()
method.
Let data be the result of
getting a copy of the bytes held by the data
parameter passed to the
verify
()
method.
Let normalizedAlgorithm be the result of
normalizing an algorithm, with
alg
set to algorithm and op
set to
"verify
".
If an error occurred, return a Promise rejected with normalizedAlgorithm.
Let realm be the relevant realm of this.
Let promise be a new Promise.
Return promise and perform the remaining steps in parallel.
If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.
If the name
member of
normalizedAlgorithm is not equal to the
name
attribute of the
[[algorithm]]
internal slot of
key then throw an InvalidAccessError
.
If the [[usages]]
internal slot of
key does not contain an entry that is "verify
", then throw an InvalidAccessError
.
Let result be the result of performing the verify operation specified by normalizedAlgorithm using key, algorithm and signature and with data as message.
Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.
Resolve promise with result.
The digest
method returns
a new Promise object that will digest data using the specified
AlgorithmIdentifier
.
It must act as follows:
Let algorithm be the algorithm
parameter passed to the
digest
()
method.
Let data be the result of
getting a copy of the bytes held by the data
parameter passed to the
digest
()
method.
Let normalizedAlgorithm be the result of
normalizing an algorithm, with
alg
set to algorithm and op
set to
"digest
".
If an error occurred, return a Promise rejected with normalizedAlgorithm.
Let realm be the relevant realm of this.
Let promise be a new Promise.
Return promise and perform the remaining steps in parallel.
If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.
Let digest be the result of performing the digest operation specified by normalizedAlgorithm using algorithm, with data as message.
Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.
Let result be the result of creating an ArrayBuffer
in realm, containing digest.
Resolve promise with result.
When invoked, generateKey
MUST perform the
following steps:
Let algorithm, extractable and usages
be the algorithm
, extractable
and keyUsages
parameters passed to the
generateKey
()
method,
respectively.
Let normalizedAlgorithm be the result of
normalizing an algorithm, with
alg
set to algorithm and op
set to
"generateKey
".
If an error occurred, return a Promise rejected with normalizedAlgorithm.
Let realm be the relevant realm of this.
Let promise be a new Promise.
Return promise and perform the remaining steps in parallel.
If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.
Let result be the result of performing the generate key operation specified by normalizedAlgorithm using algorithm, extractable and usages.
CryptoKey
object:
If the [[type]]
internal slot of
result is "secret
" or "private
" and
usages is empty, then throw a SyntaxError
.
CryptoKeyPair
object:
If the [[usages]]
internal slot of the
privateKey
attribute of
result is the empty sequence, then
throw a SyntaxError
.
Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.
Let result be the result of converting result to an ECMAScript Object in realm, as defined by [WebIDL].
Resolve promise with result.
When invoked, deriveKey
MUST perform the following steps:
Let algorithm, baseKey, derivedKeyType,
extractable and usages be the algorithm
,
baseKey
, derivedKeyType
, extractable
and
keyUsages
parameters passed to the deriveKey
()
method, respectively.
Let normalizedAlgorithm be the result of
normalizing an algorithm, with
alg
set to algorithm and op
set to
"deriveBits
".
If an error occurred, return a Promise rejected with normalizedAlgorithm.
Let normalizedDerivedKeyAlgorithmImport be the result of
normalizing an algorithm, with
alg
set to derivedKeyType and op
set to
"importKey
".
If an error occurred, return a Promise rejected with normalizedDerivedKeyAlgorithmImport.
Let normalizedDerivedKeyAlgorithmLength be the result of
normalizing an algorithm, with
alg
set to derivedKeyType and op
set to
"get key length
".
If an error occurred, return a Promise rejected with normalizedDerivedKeyAlgorithmLength.
Let realm be the relevant realm of this.
Let promise be a new Promise.
Return promise and perform the remaining steps in parallel.
If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.
If the name
member of
normalizedAlgorithm is not equal to the
name
attribute of the
[[algorithm]]
internal slot of
baseKey then throw an InvalidAccessError
.
If the [[usages]]
internal slot of
baseKey does not contain an entry that is "deriveKey
",
then throw an InvalidAccessError
.
Let length be the result of performing the get key length algorithm specified by normalizedDerivedKeyAlgorithmLength using derivedKeyType.
Let secret be the result of performing the derive bits operation specified by normalizedAlgorithm using key, algorithm and length.
Let result be the result of performing the import key operation
specified by normalizedDerivedKeyAlgorithmImport using "raw
" as
format, secret as keyData,
derivedKeyType as algorithm and using
extractable and usages.
If the [[type]]
internal slot of
result is "secret
" or "private
" and
usages is empty, then throw a SyntaxError
.
Set the [[extractable]]
internal
slot of result to extractable.
Set the [[usages]]
internal
slot of result to the normalized value of usages.
Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.
Let result be the result of converting result to an ECMAScript Object in realm, as defined by [WebIDL].
Resolve promise with result.
When invoked, deriveBits
MUST perform the following steps:
Let algorithm, baseKey and length,
be the algorithm
,
baseKey
and length
parameters passed to the
deriveBits
()
method,
respectively.
Let normalizedAlgorithm be the result of
normalizing an algorithm, with
alg
set to algorithm and op
set to
"deriveBits
".
If an error occurred, return a Promise rejected with normalizedAlgorithm.
Let realm be the relevant realm of this.
Let promise be a new Promise.
Return promise and perform the remaining steps in parallel.
If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.
If the name
member of
normalizedAlgorithm is not equal to the
name
attribute of the
[[algorithm]]
internal slot of
baseKey then throw an InvalidAccessError
.
If the [[usages]]
internal slot of
baseKey does not contain an entry that is "deriveBits
",
then throw an InvalidAccessError
.
Let bits be the result of performing the derive bits operation specified by normalizedAlgorithm using baseKey, algorithm and length.
Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.
Let result be the result of creating an ArrayBuffer
in realm, containing bits.
Resolve promise with result.
When invoked, the importKey
method MUST perform the following steps:
Let format, algorithm, extractable and
usages, be the format
, algorithm
,
extractable
and keyUsages
parameters passed to the importKey
()
method, respectively.
raw
",
"pkcs8
", or "spki
":
If the keyData
parameter passed to the
importKey
()
method is a
JsonWebKey
dictionary, throw a
TypeError
.
Let keyData be the result of
getting a copy of the bytes held by the
keyData
parameter passed to the
importKey
()
method.
jwk
":
If the keyData
parameter passed to the
importKey
()
method is not a
JsonWebKey
dictionary, throw a
TypeError
.
Let keyData be the keyData
parameter passed to the
importKey
()
method.
Let normalizedAlgorithm be the result of
normalizing an algorithm, with
alg
set to algorithm and op
set to
"importKey
".
If an error occurred, return a Promise rejected with normalizedAlgorithm.
Let realm be the relevant realm of this.
Let promise be a new Promise.
Return promise and perform the remaining steps in parallel.
If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.
Let result be the CryptoKey
object that
results from performing the import key operation specified by
normalizedAlgorithm using keyData,
algorithm,
format, extractable and usages.
If the [[type]]
internal slot of
result is "secret
" or "private
" and
usages is empty, then throw a SyntaxError
.
Set the [[extractable]]
internal
slot of result to extractable.
Set the [[usages]]
internal
slot of result to the normalized value of usages.
Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.
Let result be the result of converting result to an ECMAScript Object in realm, as defined by [WebIDL].
Resolve promise with result.
Support of "raw
" key formats is encouraged for interoperability. Web developers should consult the test-suite for
detailed information on implementations support of other key formats.
When invoked, the exportKey
method MUST perform the following steps:
Let format and key be the format
and
key
parameters passed to the exportKey
()
method, respectively.
Let realm be the relevant realm of this.
Let promise be a new Promise.
Return promise and perform the remaining steps in parallel.
If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.
If the name
member of the [[algorithm]]
internal slot of
key does not identify a registered algorithm
that supports the export key operation, then throw a NotSupportedError
.
If the [[extractable]]
internal slot
of key is false, then throw an InvalidAccessError
.
Let result be the result of performing the export key operation
specified by the [[algorithm]]
internal slot of key using key and format.
Queue a global task on the crypto task source, given realm's global object, to perform the remaining steps.
Resolve promise with result.
Support of "raw
" key formats is encouraged for interoperability. Web developers should consult the test-suite for
detailed information on implementations support of other key formats.
When invoked, the wrapKey
method MUST perform the following steps:
Let format, key, wrappingKey and
algorithm be the format
, key
,
wrappingKey
and wrapAlgorithm
parameters passed to the
wrapKey
()
method,
respectively.
Let normalizedAlgorithm be the result of
normalizing an algorithm, with
alg
set to algorithm and op
set to
"wrapKey
".
If an error occurred, let normalizedAlgorithm be the result of
normalizing an algorithm, with
alg
set to algorithm and op
set to
"encrypt
".
If an error occurred, return a Promise rejected with normalizedAlgorithm.
Let realm be the relevant realm of this.
Let promise be a new Promise.
Return promise and perform the remaining steps in parallel.
If the following steps or referenced procedures say to throw an error, queue a global task on the crypto task source, given realm's global object, to reject promise with the returned error; and then terminate the algorithm.
If the name
member of
normalizedAlgorithm is not equal to the
name
attribute of the
[[algorithm]]
internal slot of
wrappingKey then throw an InvalidAccessError
.
If the [[usages]]
internal slot of
wrappingKey does not contain an entry that is "wrapKey
",
then throw an