The SubtleCrypto.deriveKey()
method returns a Promise
of a newly generated CryptoKey
derivated from a master key and a specific algorithm given as parameters.
Syntax
var result = crypto.deriveKey(algo, masterKey, derivedKeyAlgo, extractable, keyUsages)
;
Parameters
algo
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}
wheresalt
is anArrayBuffer
or anArrayBufferView
,iterations
is the number of iterations andhash
is aDOMString
identifying the hashing algorithm to use (currently only"SHA-1"
is supported).{"name": "HKDF-CTR", hash, label, context}
masterKey
is aCryptoKey
representing the master key to be used by the key derivation algorithm.derivedKeyAlgo
is an object defining the algorithm the derived key will be used for or aDOMString
as a shortcut for{"name": derivedKeyAlgo}
. For AES alength
property is also required, possible values are 128, 192 or 256 bits.extractable
is aBoolean
indicating if the key can be extracted from theCryptoKey
object at a later stage.keyUsages
is anArray
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.
Return value
result
is aPromise
that returns the derivated key as aCryptoKey
or aCryptoKeyPair
.
Exceptions
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 theCryptoKey.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
whenkeyUsages
is empty but the unwrapped key is of type"secret"
or"private"
.
Example
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.
Specifications
Specification | Status | Comment |
---|---|---|
Web Cryptography API The definition of 'SubtleCrypto.deriveKey()' in that specification. |
Candidate Recommendation | Initial definition. |
Browser compatibility
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | 37 | 34 (34) | No support | ? | No support |
PBKDF2 |
42 | 34 (34) | No support | ? | No support |
HKDF-CTR |
42 | No support | No support | No support | No support |
DH |
No support | 35 (35) | No support | No support | No support |
Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Basic support | (Yes) | 37 | 34.0 (34) | No support | ? | No support |
PBKDF2 |
(Yes) | 42 | 34.0 (34) | No support | ? | No support |
HKDF-CTR |
(Yes) | 42 | No support | No support | No support | No support |
DH |
No support | No support | 35.0 (35) | No support | No support | No support |
See also
Crypto
andCrypto.subtle
.SubtleCrypto
, the interface it belongs to.