skip to Main Content
      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.

2

Answers


  1. There is a bug in importKey, where the wrong error is being reported to you.

    The real problem is that ECDH keys cannot be exported or imported in raw format. You need to instead use pkcs8 as the format.

    Login or Signup to reply.
  2. The key usage deriveKey is only permitted for private keys. For public keys, an empty list must be used for the key usages.
    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:

    (async () => {
    
    // create key pair
    let keyPair = await window.crypto.subtle.generateKey(
        { name: "ECDH", namedCurve: "P-256" },
        true,
        ["deriveKey"],
    );
    console.log("keyPair:", keyPair)     
    
    // export raw public key (uncompressed format)
    let publicKey = await window.crypto.subtle.exportKey("raw", keyPair.publicKey)
    console.log("publicKey:", ab2hex(publicKey))
    
    // import raw public key (uncompressed format)
    let importedPublicKey = await window.crypto.subtle.importKey(
        "raw", 
        publicKey,                               // valid raw public key in uncompressed froamt
        { name: "ECDH", namedCurve: "P-256" },
        false,                          
        []                                       // empty list
    ); 
    console.log("importedPublicKey:", importedPublicKey)
      
    function ab2hex(ab) { 
        return Array.prototype.map.call(new Uint8Array(ab), x => ('00' + x.toString(16)).slice(-2)).join('');
    }
    
    })();
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search