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

SubtleCrypto: sign() method missing Ed25519 in Supported algorithms #30886

Closed
Tracked by #34708
guest271314 opened this issue Dec 9, 2023 · 10 comments · Fixed by #34989
Closed
Tracked by #34708

SubtleCrypto: sign() method missing Ed25519 in Supported algorithms #30886

guest271314 opened this issue Dec 9, 2023 · 10 comments · Fixed by #34989
Assignees
Labels
area: Web Crypto Content:WebAPI Web API docs goal: up-to-date (Experimental label) Issues about outdated content.

Comments

@guest271314
Copy link
Contributor

MDN URL

https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/sign

What specific section or headline is this issue about?

Supported algorithms

What information was incorrect, unhelpful, or incomplete?

Missing Ed25519.

What did you expect to see?

Ed25519 algorithm listed.

Do you have any supporting links, references, or citations?

GoogleChromeLabs/webbundle-plugins#11 (comment)

Yes. Node support is unfortunately required as long as Ed25519 keys are not supported by SubtleCrypto so that JS-only library would be possible. So node is needed in order to sign a web bundle, as Node's Crypto API supports Ed25519 keys.

GoogleChromeLabs/webbundle-plugins#11 (comment)

It's not limited to node-only as there's also golang version of the package. Whenever the support for ed25519 keys is added to SubtleCrypto, it'll be rather simple to create a browser-only version of the wbn-sign package. Web bundles are still experimental and I'm sure the tooling coverage improves when use of IWAs increases.

This modified version of Deno test code https://github.com/denoland/deno/blob/ca64771257d23ceee97e882965269702c359f6aa/cli/tests/node_compat/test/parallel/test-webcrypto-sign-verify.js#L115-L133 logs true on Chromium Version 122.0.6170.0 (Developer Build) (64-bit).

// Test Sign/Verify Ed25519
{
  
  async function test(data) {
    const {subtle} = self.crypto;
    const ec = new TextEncoder();
    const { publicKey, privateKey } = await subtle.generateKey({
      name: 'Ed25519',
    }, true, ['sign', 'verify']);

    const signature = await subtle.sign({
      name: 'Ed25519',
    }, privateKey, ec.encode(data));

    console.log(await subtle.verify({
      name: 'Ed25519',
    }, publicKey, signature, ec.encode(data)));
  }

  test('hello world').catch(console.error);
}

Do you have anything more you want to share?

No response

@guest271314 guest271314 added the needs triage Triage needed by staff and/or partners. Automatically applied when an issue is opened. label Dec 9, 2023
@github-actions github-actions bot added Content:WebAPI Web API docs and removed Content:WebAPI Web API docs labels Dec 9, 2023
@guest271314
Copy link
Contributor Author

Secure Curves in the Web Cryptography API

The Implementation of the Ed25519 algorithm landed Chromium in Nov 2022 and shipped in Chrome 110.0.5424.0. The X25519 key sharing algorithm took more time due to the review process, but it finally landed in March 2023 and has been shipped in Chrome since 113.0.5657.0.

@caugner caugner added the goal: completeness (Experiment label) Issues about content missing important/relevant details. label Dec 18, 2023
@bsmth bsmth self-assigned this Dec 21, 2023
@bsmth
Copy link
Member

bsmth commented Jan 19, 2024

Thanks for opening this one. That page is targeting this spec: https://w3c.github.io/webcrypto/#SubtleCrypto-method-sign which does not include Ed25519 or others.

The spec that covers the algorithms with the missing secure curves is at this state:

This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track.
...
This is an unofficial proposal.

Although there's partial / experimental support, it looks a little early to include these at the moment. If we were to add anything, it would likely be under https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto#supported_algorithms with some indication of status and resources to learn more.

@bsmth bsmth added goal: up-to-date (Experimental label) Issues about outdated content. waiting for implementations Waiting for feature to be implemented in browsers and removed needs triage Triage needed by staff and/or partners. Automatically applied when an issue is opened. goal: completeness (Experiment label) Issues about content missing important/relevant details. labels Jan 19, 2024
@guest271314
Copy link
Contributor Author

There's a whole bunch of proposals that are implemented in the wild and are documented on MDN. E.g., WICG File System Access API, not to be confused with WHATWG File System Standard. Direct Sockets in Isolated Web Apps are shipped on Chromium. That's how I can create a TCPSocket in the browser.

Node.js, Deno, Bun, and Chromium 122 all implement Ed25519.

The problem is the authors wbn-sign quoted MDN as the source for information re Ed25519 algorithm as a reason for using Node.js crypto to sign the Web Bundle, and Node.js crypto cannot be polyfilled as far as I can tell. It took a while to figure this out. When I did I used the same Web Cryptography API code for Node.js, Deno, and Bun

Next I'm going to use the same code in the browser, substituting WICG File System Access API for Node.js fs.

This has to be written up somewhere on MDN Web Docs so people can't make excuses for why they are using Node.js crypto for Ed25519, as if only node implements the algorithm, and point to MDN omission as canonical source.

@guest271314
Copy link
Contributor Author

@bsmth I see the "waiting for implementations" label. Chromium and Chrome, Node.js, Deno, and Bun all implement Ed25519. Chromium and Chrome and Deno directly via Web Cryptography API, Bun using const {webcrypto} = "node:crypto". I actually haven't tested Firefox Nightly 123 yet. How many (more) implementations are you looking for or do you need to write this up in MDN Web Docs so folks can't say, look, MDN doesn't include the algorithm, therefore it must not be implemented by anybody other than Node.js, and not via webcrypto, rather via the internal crypto?

@bsmth
Copy link
Member

bsmth commented Jan 19, 2024

Thanks for the feedback. Where I've added waiting for implementations, I'm specifically talking about the experimental work that is intended to land in SubtleCrypto. i.e., it's not possible to do window.crypto.subtle.sign('Ed25519'... anywhere yet as it's not even landed on the spec, or have I misunderstood?

For some context, I got started on this already today adding an ed25519 example to https://github.com/mdn/dom-examples/tree/main/web-crypto/sign-verify before I realized why it wasn't working on Chrome canary and came back to re-read the issue and linked resources.

I'm more than happy to include documentation for the missing algos, but it needs to be clear it's not part of this API yet. Can we consider where to include it or pitfalls readers should be aware of?

@guest271314
Copy link
Contributor Author

Thanks for the feedback. Where I've added waiting for implementations, I'm specifically talking about the experimental work that is intended to land in SubtleCrypto. i.e.,

That implementation has already landed in

i.e., it's not possible to do window.crypto.subtle.sign('Ed25519'... anywhere yet as it's not even landed on the spec, or have I misunderstood?

Yes, it's possible. I linked to the repositories above

https://github.com/guest271314/webbundle/blob/50d73ff7b6403bf62c5eff3492887a1194401e83/index.js#L45

await webcrypto.subtle.sign(algorithm, cryptoKey.privateKey, data),

The works in Node.js, Deno, and Bun using the same code. The code also works on Chromium 122 Developer Build.

Screenshot_2024-01-19_17-12-45

This is the MDN source the GoogleChrome author referenced, which turns out is inaccurate information.

GoogleChromeLabs/webbundle-plugins#11 (comment)

Yes. Node support is unfortunately required as long as Ed25519 keys are not supported by SubtleCrypto so that JS-only library would be possible. So node is needed in order to sign a web bundle, as Node's Crypto API supports Ed25519 keys.

See this Deno test https://github.com/denoland/deno/blob/ca64771257d23ceee97e882965269702c359f6aa/cli/tests/node_compat/test/parallel/test-webcrypto-sign-verify.js#L115-L133

// Test Sign/Verify Ed25519
{
  async function test(data) {
    const ec = new TextEncoder();
    const { publicKey, privateKey } = await subtle.generateKey({
      name: 'Ed25519',
    }, true, ['sign', 'verify']);

    const signature = await subtle.sign({
      name: 'Ed25519',
    }, privateKey, ec.encode(data));

    assert(await subtle.verify({
      name: 'Ed25519',
    }, publicKey, signature, ec.encode(data)));
  }

  test('hello world').then(common.mustCall());
}

and read this Secure Curves in the Web Cryptography API which might be the source of your idea that Ed25519 is not implemented. It's implemented in a lot of JavaScript runtimes and Chrome and Chromium, listed above - not in Firefox Nightly 123

Screenshot_2024-01-19_17-21-53

That's 1 not implemented out of 4 separate JavaScript runtimes (counting Chromium and Chrome as 1, even though they are not the same browser).

Just run the code here https://github.com/guest271314/webbundle using Node.js (I'm running nightly release 22), Deno, Bun and run this code

const algorithm = { name: "Ed25519" };
const encoder = new TextEncoder();
const cryptoKey = await crypto.subtle.generateKey(
  algorithm,
  true, /* extractable */
  ["sign", "verify"],
);

console.log(await crypto.subtle.sign(algorithm, cryptoKey.privateKey, new Uint8Array([255])));

on Chrome-For-Testing https://github.com/GoogleChromeLabs/chrome-for-testing or Chromium Developer Build https://download-chromium.appspot.com/ or Chrome Unstable Build (Canary) to verify for yourself. Just because Firefox hasn't implemented a standard or API doesn't mean multiple other vendors have not.

@guest271314
Copy link
Contributor Author

@bsmth PR for sign-verify example mdn/dom-examples#247

@bsmth
Copy link
Member

bsmth commented Jan 25, 2024

@bsmth PR for sign-verify example mdn/dom-examples#247

Thank you very much, I will take a look shortly

@bsmth
Copy link
Member

bsmth commented Feb 22, 2024

See also w3c/webcrypto#362

@hamishwillee
Copy link
Collaborator

FYI I'm looking at this as part of #34989 because FF129 implements this. Great you've done the hard work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Web Crypto Content:WebAPI Web API docs goal: up-to-date (Experimental label) Issues about outdated content.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants