Skip to content

ECDH P-256: Exporting public key to 'spki' format produces an invalid result #15523

@Menecats

Description

@Menecats

Exporting a ECDH P-256 key in the spki format produced a non-valid key.

The following two scripts allow to export and import a spki key:

Export:

function toHex(buf: ArrayBuffer): string {
  let out = "";
  new Uint8Array(buf).forEach((b) => out += b.toString(16).padStart(2, "0"));
  return out.toUpperCase();
}

const algorithm = {
  name: "ECDH",
  namedCurve: "P-256",
}

const { publicKey } = await window.crypto.subtle.generateKey(algorithm, true, ["deriveKey", "deriveBits"]);

const keySPKI = await crypto.subtle.exportKey('spki', publicKey);
const keyHEX = toHex(keySPKI)

console.log(keyHEX);

Import:

function fromHex(value: string): Uint8Array {
  if (value.length % 2 !== 0) {
    throw new Error(
      `Input cannot contain a hex value, 'value' length must be even`,
    );
  }
  const tester = /^(?:[a-f0-9]{2})*$/i;
  if (!tester.test(value)) {
    throw new Error(`Input does not contain a valid hex value`);
  }

  const out = new Uint8Array(value.length / 2);
  for (let i = 0; i < value.length; i += 2) {
    const val = value.substring(i, i + 2);
    out[i / 2] = parseInt(val, 16);
  }
  return out;
}


const algorithm = {
  name: "ECDH",
  namedCurve: "P-256",
}

const keyHEX = prompt('Type the key and press [Enter]:')
const keySPKI = fromHex(keyHEX);

const publicKey = await crypto.subtle.importKey('spki', keySPKI, algorithm, false, []);

I've performed the following tests:

  • Export a key on deno and import it on deno
  • Export a key on deno and import it on chrome
  • Export a key on chrome and import it on deno
  • Export a key on chrome and import it on chrome

The import of the key generated by deno both on deno itself and on chrome threw an exception:

  • On deno a DOMException: unknown algorithm
  • On chrome a generic Uncaught Error

The import of the key generated by chrome both on deno and on chrome itself did work without any problem.

The version of deno used for these tests is 1.24.3
The version of chrome used for these tests is 104

The OS used during the tests is: Windows 10.0.19044.1889

Here follows some example of public keys generated both by deno and by chrome:
Deno:

3057301106052B8104010C06082A8648CE3D03010703420004F653BAF386F73A3E11AC9FB235706781CB8BB24800C2EE5554F378240BA9AC1AC0FFBF3D29E3646D8661328493C19D76170A1B3FE179570E8593F4A9979DB77A

3057301106052B8104010C06082A8648CE3D030107034200048D6A68B43A4F3895427A5F433AC80FCCDD106AD91B0EDABBDD100A02EE6D68B9BB37BAACDB8C7938DA30D598735A4B08AE047F049C31765DB33B232B0DAD6171

3057301106052B8104010C06082A8648CE3D03010703420004E6E13F99453614D7311D9421CBC349D5C91D9EA0A925B4705E2B2C1002F7990CB14B00E56B77A38503982C9D13C4656B62C3280628633ECBE7024AEBA2C27C29

3057301106052B8104010C06082A8648CE3D03010703420004564057A9774B5D14C30C0A7204911647B8C88C5C01DF93F0114CE2183792A22EF36A1347EEDCC4D8C8F7AEFBE4C8B9C1FE9AFBE861E741D05ADEEA0A31FE80B0

Chrome:

3057301106052B8104010C06082A8648CE3D03010703420004564057A9774B5D14C30C0A7204911647B8C88C5C01DF93F0114CE2183792A22EF36A1347EEDCC4D8C8F7AEFBE4C8B9C1FE9AFBE861E741D05ADEEA0A31FE80B0

3057301106052B8104010C06082A8648CE3D03010703420004564057A9774B5D14C30C0A7204911647B8C88C5C01DF93F0114CE2183792A22EF36A1347EEDCC4D8C8F7AEFBE4C8B9C1FE9AFBE861E741D05ADEEA0A31FE80B0

3057301106052B8104010C06082A8648CE3D03010703420004564057A9774B5D14C30C0A7204911647B8C88C5C01DF93F0114CE2183792A22EF36A1347EEDCC4D8C8F7AEFBE4C8B9C1FE9AFBE861E741D05ADEEA0A31FE80B0

3057301106052B8104010C06082A8648CE3D03010703420004564057A9774B5D14C30C0A7204911647B8C88C5C01DF93F0114CE2183792A22EF36A1347EEDCC4D8C8F7AEFBE4C8B9C1FE9AFBE861E741D05ADEEA0A31FE80B0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions