let randKey = window.crypto.getRandomValues(new Uint8Array(64));
let importedKey = await window.crypto.subtle.importKey("raw", randKey,
{
name: "ECDH",
namedCurve: "P-256",
},
false,
["deriveKey"]
);
Yet this fails with the error: Uncaught DOMException: Cannot create a key using the specified key usages.
How do I import a key to be used in key derivation?
I am basing my code off this snippet from the subtle crypto docs, which works perfectly:
let bobsKeyPair = await window.crypto.subtle.generateKey(
{
name: "ECDH",
namedCurve: "P-256",
},
false,
["deriveKey"],
);
But I want to do this with a key that has already been generated.
I found another stackoverflow question that said to use []
in the usages section, but all that did was change the error to just be Uncaught Error
.
Since your raw P-256 key has 64 bytes, I assume that you want to import a public ECDH key (although you don't mention this explicitly).
For public ECDH keys, an empty list must be used for the key usages. The key usage
deriveKey
is only permitted for private keys.In addition, the raw public key must be passed in compressed or uncompressed format and it must of course be a valid key for the curve in question (not an arbitrary byte sequence).
In the following code, first a valid raw public key in uncompressed format is generated. To do this, a P-256 key pair is generated, whose public key is then exported in raw, uncompressed format. This is then used to demonstrate how such a key can be imported:
For completeness: In addition to the raw (uncompressed or compressed) format, public ECDH keys can also be imported in X.509/SPKI format (DER encoded), or in JWK format.
Private ECDH keys cannot be imported in raw format, but only in PKCS#8 format (DER encoded), or in JWK format. The PKCS#8 format for private keys has already been pointed out in the other answer. Permitted key usages are
deriveKey
orderiveBits
.Note: Keys in PKCS#8 format or X.509/SPKI format can be loaded and inspected in an ASN.1 parser.
Code sample for the import of a private key:
Edit - regarding your question from the comment:
The direct import of a raw private ECDH key is not supported by WebCrypto as described above. In the case of a raw private key, the key must be converted into a format that is supported by WebCrypto, i.e. PKCS#8 or JWK. Regarding PKCS#8, it is best to use a suitable library. Conversion to a JWK, on the other hand, is quite simple.
The following code provides an example of converting a raw ECDH key into a JWK and then importing it: