The SubtleCrypto.deriveKey()
method returns a Promise
of a newly generated CryptoKey
derived from a master key and a specific algorithm given as parameters.
const result = crypto.subtle.deriveKey( algorithm, masterKey, derivedKeyAlgorithm, extractable, keyUsages);
algorithm
is an object defining the derivation algorithm to use. Supported values are: {"name": "ECDH", "public": publicKey}
{"name": "DH", "public": publicKey}
{"name": "PBKDF2", salt, iterations, hash}
where salt
is an ArrayBuffer
or an ArrayBufferView
, iterations
is the number of iterations and hash
is a DOMString
identifying the hashing algorithm to use.{"name": "HKDF-CTR", hash, label, context}
masterKey
is a CryptoKey
representing the master key to be used by the key derivation algorithm.derivedKeyAlgorithm
is an object defining the algorithm the derived key will be used for or a DOMString
as a shortcut for {"name": derivedKeyAlgo}
. For AES a length
property is also required, possible values are 128, 192 or 256 bits.extractable
is a Boolean
indicating if the key can be extracted from the CryptoKey
object at a later stage.keyUsages
is an Array
indicating what can be done with the derivated key. Possible values of the array are: "encrypt"
, allowing the key to be used for encrypting messages."decrypt"
, allowing the key to be used for decrypting messages."sign"
, allowing the key to be used for signing messages."verify"
, allowing the key to be used for verifying the signature of messages."deriveKey"
, allowing the key to be used as a base key when deriving a new key."deriveBits"
, allowing the key to be used as a base key when deriving bits of data for use in cryptographic primitives."wrapKey"
, allowing the key to wrap a symmetric key for usage (transfer, storage) in unsecure environments."unwrapKey"
, allowing the key to unwrap a symmetric key for usage (transfer, storage) in unsecure environments.result
is a Promise
that returns the derivated key as a CryptoKey
or a CryptoKeyPair
.The promise is rejected when one of the following exceptions are encountered:
InvalidAccessError
when the master key is not a key for the requested derivation algorithm or if the CryptoKey.usages
value of that key doesn't contain "deriveKey"
.NotSupported
when trying to use an algorithm that is either unknown or isn't suitable for derivation, or if the algorithm requested for the derived key doesn't define a key length.SyntaxError
when keyUsages
is empty but the unwrapped key is of type "secret"
or "private"
.Here's an example showing how to use deriveKey() to create a Secure Remote Password (also known as Proof of Secret) from a user's password.
// salt should be Uint8Array or ArrayBuffer var saltBuffer = Unibabel.hexToBuffer('e85c53e7f119d41fd7895cdc9d7bb9dd'); // don't use naïve approaches for converting text, otherwise international // characters won't have the correct byte sequences. Use TextEncoder when // available or otherwise use relevant polyfills var passphraseKey = Unibabel.utf8ToBuffer("I hëart årt and £$¢!"); // You should firstly import your passphrase Uint8array into a CryptoKey window.crypto.subtle.importKey( 'raw', passphraseKey, {name: 'PBKDF2'}, false, ['deriveBits', 'deriveKey'] ).then(function(key) { return window.crypto.subtle.deriveKey( { "name": 'PBKDF2', "salt": saltBuffer, // don't get too ambitious, or at least remember // that low-power phones will access your app "iterations": 100, "hash": 'SHA-256' }, key, // Note: for this demo we don't actually need a cipher suite, // but the api requires that it must be specified. // For AES the length required to be 128 or 256 bits (not bytes) { "name": 'AES-CBC', "length": 256 }, // Whether or not the key is extractable (less secure) or not (more secure) // when false, the key can only be passed as a web crypto object, not inspected true, // this web crypto object will only be allowed for these functions [ "encrypt", "decrypt" ] ) }).then(function (webKey) { return crypto.subtle.exportKey("raw", webKey); }).then(function (buffer) { var proofOfSecret = Unibabel.bufferToHex(buffer); // this proof-of-secret / secure-remote password // can now be sent in place of the user's password });
Note: Because there are no native tools to convert between Uint8Array, Unicode, hex, and base64, you'll probably want to use something like Unibabel or Buffer to convert between them.
Specification | Status | Comment |
---|---|---|
Web Cryptography API The definition of 'SubtleCrypto.deriveKey()' in that specification. | Recommendation | Initial definition. |
Desktop | ||||||
---|---|---|---|---|---|---|
Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | |
Basic support | 37 | 12 | 34
|
No | 24 | 7 |
Mobile | |||||||
---|---|---|---|---|---|---|---|
Android webview | Chrome for Android | Edge Mobile | Firefox for Android | Opera for Android | iOS Safari | Samsung Internet | |
Basic support | 37 | 37 | 12 | 34
|
24 | 7 | 6.0 |
Crypto
and Crypto.subtle
.SubtleCrypto
, the interface it belongs to.
© 2005–2018 Mozilla Developer Network and individual contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey