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

Use Web Cryptography API for wbn-sign-webcrypto, crypto-browserify throws for subtle, doesn't implement Ed25519 #786

Open
guest271314 opened this issue Jan 6, 2024 · 10 comments

Comments

@guest271314
Copy link

I'm using Web Cryptography API (with algorithm Ed25519) for the ability to run the same source code using node, deno, and bun and other JavaScript runtimes, including the browser.

I am not using Node.js node:crypto implementation, which apparently cannot be polyfilled.

From the source code of crypto-browesrify https://esm.sh/v135/[email protected]/esnext/crypto-browserify.mjs it doesn't look like Ed25519 algorithm is implemented in that module.

import { WebBundleId } from "https://esm.sh/gh/guest271314/wbn-sign-webcrypto/lib/wbn-sign.js";
TypeError: Cannot read properties of undefined (reading 'subtle')
    at l (https://esm.sh/v135/gh/guest271314/wbn-sign-webcrypto@44185e29b6/esnext/lib/wbn-sign.js:3:3508)
    at b.serialize (https://esm.sh/v135/gh/guest271314/wbn-sign-webcrypto@44185e29b6/esnext/lib/wbn-sign.js:3:5957)
    at b.serializeWithIsolatedWebAppOrigin (https://esm.sh/v135/gh/guest271314/wbn-sign-webcrypto@44185e29b6/esnext/lib/wbn-sign.js:3:6105)
    at file:///home/user/webbundle/rollup.wbn.js:52:5

Node.js v22.0.0-nightly202312315fb6305971

from

  async serialize() {
    return base32Encode(
      new Uint8Array([
        ...(await getRawPublicKey(this.key)),
        ...this.appIdSuffix,
      ]),
      "RFC4648",
      { padding: false },
    ).toLowerCase();
  }

and

https://github.com/guest271314/wbn-sign-webcrypto/blob/main/lib/utils/utils.js

export async function getRawPublicKey(publicKey) {
  // Currently this is the only way for us to get the raw 32 bytes of the public key.
  return new Uint8Array(await webcrypto.subtle.exportKey("spki", publicKey))
    .slice(-32);
}
@ije
Copy link
Member

ije commented Jan 6, 2024

seems crypto-browesrify doesn't implement the webcrypto object, you can use the global crypto.subtle object in browser

@guest271314
Copy link
Author

Yes. Unfortunately esm.sh is importing crypto-browserify. I don't have any references to crypto-browserify in my source code.

@ije
Copy link
Member

ije commented Jan 6, 2024

esm.sh will replace "node:crypto" to crypto-browserify for browsers

@guest271314
Copy link
Author

I didn't make the request from the browser. I made the request from Deno.

I'm using webcrypto object defined on node:crypto. crypto-browserfy doesn't implement webcrypto or Ed26619 algorithm. As far as I understand node:crypto can't be polyfilled.

esm.sh importing crypto-browserify is throwing errors, can't be used. The code should identify webcrypto is being used. Not import crypto-browserify. The point of https://github.com/guest271314/wbn-sign-webcrypto is to use standardized Web Cryptography API, and to not use Node.js crypto implementation.

@guest271314
Copy link
Author

In other word esm.sh importing crypto-browserify is breaking my code. See paulmillr/noble-ed25519#98 (comment)

For interop with node or webcrypto, it’s simple: just use their export and import methods.

the problem lies deeper than node api: the package in question wants to consume some specific key format.

...

All node parts have to be replaced for browser - that’s correct

So I did that. The same webscrypto code runs in deno, node, and bun. Deno has some peculiarities with regard to dynamic imports, and when building with bun I have to import Buffer module from std and define globally; when building with esbuild I don't have to define Buffer globally. Other than that I implemented npm:wbn-sign to work using Web Cryptography API instead of node:crypto, so the same code can run in multiple JavaScript runtimes, and next the browser.

I was rather surprised when I saw esm.sh was depending on crypto-browserify. I looked at the repository while researching how to go about replacing a Node.js implementation with a standardized Web Platform API implementation. I think the last update was 6 years ago? SO I couldn't use that. The browser, Node.js, Deno, and Bun implement Web Cryptograpphy API.

Nowhere in my code do I intend to use crypto-browserify.

@guest271314
Copy link
Author

You can repoduce the error by running this code https://github.com/guest271314/webbundle/blob/main/index.js and substituting

import { WebBundleId } from "https://esm.sh/gh/guest271314/wbn-sign-webcrypto/lib/wbn-sign.js";

for

import { WebBundleId } from "wbn-sign-webcrypto";

for

@ije
Copy link
Member

ije commented Jan 6, 2024

I didn't make the request from the browser. I made the request from Deno.

weird, Deno should work fine:

Screenshot 2024-01-06 at 16 27 51

@ije
Copy link
Member

ije commented Jan 6, 2024

i got a different error:

Screenshot 2024-01-06 at 16 29 11

@guest271314
Copy link
Author

I don't think you followed all of the steps here https://github.com/guest271314/webbundle before substituting import from esm.sh for wbn-sign.js.

crypto-browserify is never going to work for Ed25519 algorithm as-is. Just read the source code and observe complete absence of that algorithm.

Again, nowhere in my code do I import crypto-browserify.

@guest271314
Copy link
Author

weird, Deno should work fine:
Works for Deno. Doesn't work for Node.js.

TypeError: Cannot read properties of undefined (reading 'subtle')
    at l (https://esm.sh/v135/gh/guest271314/wbn-sign-webcrypto@44185e29b6/esnext/lib/wbn-sign.js:3:3508)
    at b.serialize (https://esm.sh/v135/gh/guest271314/wbn-sign-webcrypto@44185e29b6/esnext/lib/wbn-sign.js:3:5957)
    at b.serializeWithIsolatedWebAppOrigin (https://esm.sh/v135/gh/guest271314/wbn-sign-webcrypto@44185e29b6/esnext/lib/wbn-sign.js:3:6105)
    at file:///home/user/webbundle/index.js:24:5

Node.js v22.0.0-nightly2024010657c22e4a22

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

No branches or pull requests

2 participants