Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Menecats opened this issue Aug 21, 2022 · 1 comment · Fixed by #16152
Closed

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

Menecats opened this issue Aug 21, 2022 · 1 comment · Fixed by #16152

Comments

@Menecats
Copy link

Menecats commented Aug 21, 2022

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
@Menecats Menecats changed the title ECDH P-256: Fail to import public keys ECDH P-256: Exporting public key to 'spki' format produces an invalid result Aug 21, 2022
@panva
Copy link
Contributor

panva commented Sep 20, 2022

The result is valid but unfortunately not interoperable (even with Deno itself upon import it seems). Since that particular comment Node.js has further removed some of the non-interoperable key algorithm's support.

see w3c/webcrypto#307
see w3c/webcrypto#305
see nodejs/node#42816

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants