Accessing it

  • The WebCrypto API was enabled by default starting in Chrome 37 (August 26, 2014)
  • Access to the WebCrypto API is restricted to secure origins (which is to say https:// pages).
    • Note: In the spec, crypto.subtle is supposed to be undefined in insecure contexts, whereas in Chrome it is defined however any operation on it fails with NotSupportedError. (This will be updated in the future).

Standards compliance

Chromium's implementation follows the Web Cryptography API Editor's Draft.

Be sure to refer to the copy of the spec on github NOT the one hosted on w3c.org.
The version on w3c.org is horribly out of date (as of October 3 2016).

Reporting bugs

Supported algorithms (as of Chrome 53)

The WebCrypto specification does not mandate any particular algorithms.
At this time Chromium implements all of the algorithms described by the main specification:

 Algorithm  Supported  Notes
 SHA-1  YES  
 SHA-256  YES  
 SHA-384  YES  
 SHA-512  YES  

Abandoned algorithms

Earlier drafts of the specification contained additional algorithms, which have since been pulled from both the spec and from Chromium's implementation:

 Algorithm Supported Notes
  • No longer part of the spec
  • Was never implemented by Chrome
  • No longer part of the spec
  • Was never implemented by Chrome
 Diffie-Hellman NO
  • No longer part of the spec
  • Was never implemented by Chrome
 Concat KDF NO
  • No longer part of the spec
  • Was never implemented by Chrome
  • No longer part of the spec
  • Was never implemented by Chrome
  • The spec has redefined this as redefined this as HKDF
  • No longer part of the spec.
  • Chrome supported this in early days before Web Crypto was enabled by default, but has since dropped support.

RSA support

    • The modulus length must be a multiple of 8 bits
    • The modulus length must be >= 256  and <= 16384 bits
    • When generating RSA keys the public exponent must be 3 or 65537. This limitation does not apply when importing keys.

AES support

    • The supported key sizes are:
      • 128 bits
      • 256 bits
      • 192 bit AES keys are not supported

EC support

Supported key formats

Chromium's WebCrypto implementation supports all of the key formats - "raw", "spki", "pkcs8", "jwk", with the following caveats:

  • There are differences in DER key format handling between Web Crypto implementations. Where possible for compatibility prefer using "raw" keys or "jwk" which have better interoperability.

  • When importing/exporting "spki" and "pkcs8" formats, the only OIDs supported by Chromiumare those recognized by OpenSSL/BoringSSL.
    • Importing ECDH keys does not accept id-ecDH. The OID must instead be id-ecPublicKey (This can cause problems importing keys generated by Firefox; use "raw" EC keys as a workaround; Chromium in this case is not spec compliant)
    • Importing RSA-PSS keys does not accept id-RSASSA-PSS. The OID must instead be rsaEncryption
    • Importing RSA-OAEP keys does not accept id-RSAES-OAEP. The OID must instead be rsaEncryption.
    • Exporting ECDH keys uses OID id-ecPublicKey, whereas the WebCrypto spec says to use id-ecDH.
    • Exporting RSA-PSS keys uses OID rsaEncryption, whereas the WebCrypto spec says to use RSA-PSS.
    • Exporting RSA-OAEP keys uses OID rsaEncryption, whereas the WebCrypto spec says to use id-RSAES-OAEP.

Examples of how to use WebCrypto

Some examples of using WebCrypto can be found in the Blink LayoutTests.

(These can't be run directly in the browser because they access functionality from the test harness, however it gives an idea of how to call the various operations)

Usage data for WebCrypto

Google Chrome measures how commonly WebCrypto algorithms and methods are across web pages.

To explore the data use the Chromium feature stack rank dashboard. This counts the number of pageloads that made use of the given feature (internal users can navigate an equivalent histogram using "WebCore.FeatureObserver").

For details on how the metrics are measured read the comment block in CryptoHistograms.h.

Here is the correspondence between the feature names found on the Chromium feature stack rank dashboard and WebCrypto's operations/algorithms:

 Feature  WebCrypto method
 CryptoGetRandomValues   crypto.getRandomValues()
 SubtleCryptoEncrypt  crypto.subtle.encrypt()
 SubtleCryptoDecrypt  crypto.subtle.decrypt() 
 SubtleCryptoSign  crypto.subtle.sign() 
 SubtleCryptoVerify  crypto.subtle.verify() 
 SubtleCryptoDigest  crypto.subtle.digest()
 SubtleCryptoGenerateKey  crypto.subtle.generateKey() 
 SubtleCryptoImportKey  crypto.subtle.importKey() 
 SubtleCryptoExportKey  crypto.subtle.exportKey() 
 SubtleCryptoDeriveBits  crypto.subtle.deriveBits()
 SubtleCryptoDeriveKey  crypto.subtle.deriveKey() 
 SubtleCryptoWrapKey  crypto.subtle.wrapKey() 
 SubtleCryptoUnwrapKey  crypto.subtle.unwrapKey() 

 Feature WebCrypto algorithm
 CryptoAlgorithmAesCbc   AES-CBC
 CryptoAlgorithmHmac  HMAC
 CryptoAlgorithmRsaSsaPkcs1v1_5  RSASSA-PKCS1-v1_5
 CryptoAlgorithmSha1  SHA-1
 CryptoAlgorithmSha256  SHA-256
 CryptoAlgorithmSha384  SHA-384 
 CryptoAlgorithmSha512  SHA-512
 CryptoAlgorithmAesGcm  AES-GCM
 CryptoAlgorithmRsaOaep  RSA-OAEP
 CryptoAlgorithmAesCtr  AES-CTR
 CryptoAlgorithmAesKw  AES-KW
 CryptoAlgorithmRsaPss  RSA-PSS
 CryptoAlgorithmEcdsa  ECDSA
 CryptoAlgorithmEcdh  ECDH
 CryptoAlgorithmHkdf  HKDF
 CryptoAlgorithmPbkdf2  PBKDF2

Chromium developer's guide

This section is intended for Chromium developers writing patches to address WebCrypto bugs/features.

Code location reference

Running the Chromium unit-tests

cd src
ninja -C out/Debug components_unittests
./out/Debug/components_unittests --gtest_filter="WebCrypto*"

Running the Blink LayoutTests

cd src/third_party/WebKit
ninja -C out/Debug blink_tests
./Tools/Scripts/run-webkit-tests --debug crypto

Getting "XOpenDisplay failed" when running unittests

Unfortunately components_unittests requires a display to run, even though WebCrypto itself has no such dependency. If you are running from a terminal and get this error the easiest fix is to use Xvfb to create a mock display server (on port 4 in my example)

#Run this in the background....
Xvfb :4 -screen 0 1024x768x24

# And once it is up, re-run the unit-tests with its display port
DISPLAY:4 ./out/Debug/components_unittests --gtest_filter="WebCrypto*"