WebCrypto
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
- Issues with the implementation should be filed on Chromium's bug tracker, and given the component Blink>WebCrypto.
- Issues with the Web Cryptography specification should be filed on the github.
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 RSASSA-PKCS1-v1_5 YES RSA-PSS YES RSA-OAEP YES ECDSA YES ECDH YES AES-CTR YES AES-CBC YES AES-GCM YES AES-KW YES HMAC YES SHA-1 YES SHA-256 YES SHA-384 YES SHA-512 YES HKDF YES PBKDF2 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 AES-CMAC NO
No longer part of the spec Was never implemented by Chrome AES-CFB NO
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 HKDF-CTR NO
No longer part of the spec Was never implemented by Chrome The spec has redefined this as href="https://github.com/w3c/webcrypto/issues/27">redefined this as HKDF</a></td>
RSAES-PKCS1-v1_5 NO
No longer part of the spec. Chrome supported this in early days before Web Crypto was enabled by default, but has since dropped support.</td>
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
* The supported
[namedCurves](https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#dfn-NamedCurve)
are:
* P-256
* P-384
* P-521
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
-
src/components/webcrypto Contains the actual crypto algorithm implementations (HMAC, ECDH, RSA-PSS, etc.).
-
src/components/test/data/webcrypto Test data used by src/components/webcrypto. Note that more extensive tests live in LayoutTests, and these will eventually be transitioned there too.
-
src/third_party/WebKit/LayoutTests/crypto The end-to-end Javascript tests that exercise WebCrypto's crypto.subtle.* methods.
-
src/third_party/WebKit/public/platform/WebCrypto.h Public interface that defines the Blink <--> Chromium layer
-
src/third_party/WebKit/Source/modules/crypto The Blink layer (responsible for interacting with the Javascript), and then calling into Chromium side using the WebCrypto interface.
-
src/third_party/WebKit/Source/bindings/modules/v8/ScriptValueSerializerForModules.cpp Implements the structured clone for CryptoKey
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 1024x768x24And once it is up, re-run the unit-tests with its display port
DISPLAY:4 ./out/Debug/components_unittests --gtest_filter="WebCrypto*"