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

crypto: clarify require("crypto").getRandomValues is Node.js specific #41782

Merged
merged 4 commits into from
Feb 22, 2022

Conversation

aduh95
Copy link
Contributor

@aduh95 aduh95 commented Jan 31, 2022

Refs: #41779
Refs: #41760

@aduh95 aduh95 requested review from jasnell and targos January 31, 2022 10:43
@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/crypto

@nodejs-github-bot nodejs-github-bot added crypto Issues and PRs related to the crypto subsystem. needs-ci PRs that need a full CI run. labels Jan 31, 2022
lib/crypto.js Outdated Show resolved Hide resolved
@aduh95
Copy link
Contributor Author

aduh95 commented Feb 2, 2022

@jasnell could you help us here? It seems there is a confusion on what is the plan for exposing a crypto object on the global scope. Is the plan:

  • Exposing require('crypto') as crypto everywhere?
  • Exposing require('crypto').webcrypto as crypto everywhere, breaking change for the REPL?
  • Exposing require('crypto').webcrypto as crypto on files, keep exposing require('crypto') as crypto on the REPL?

If it's the latter, then I guess we should land this PR, as well as #41760, but this would need your input to move forward.

@jasnell
Copy link
Member

jasnell commented Feb 2, 2022

My preference is exposing require('crypto') as the global.

@aduh95
Copy link
Contributor Author

aduh95 commented Feb 2, 2022

My preference is exposing require('crypto') as the global.

This is going to create all sort of compatibility problems (I've been myself affected by #41760), I'm -1 on this idea. Adding it to the TSC agenda so we can discuss this further.

@aduh95 aduh95 added the tsc-agenda Issues and PRs to discuss during the meetings of the TSC. label Feb 2, 2022
@tniessen
Copy link
Member

tniessen commented Feb 2, 2022

Exposing require('crypto').webcrypto as crypto on files, keep exposing require('crypto') as crypto on the REPL?

I suggested this when talking to @jasnell earlier, except that I'd maybe add the aliases to crypto only in the REPL. (Not sure if it's a good idea after all.)

@jasnell
Copy link
Member

jasnell commented Feb 5, 2022

One possible approach we can take here is to modify Node.js' crypto to extend from Web Crypto crypto. Specifically, something like:

class NodeCrypto extends Crypto {
  // ... add the Node.js stuff...
};

module.exports = new NodeCrypto();

@aduh95
Copy link
Contributor Author

aduh95 commented Feb 6, 2022

One possible approach we can take here is to modify Node.js' crypto to extend from Web Crypto crypto. Specifically, something like:

class NodeCrypto extends Crypto {
  // ... add the Node.js stuff...
};

module.exports = new NodeCrypto();

It wouldn't help folks doing import { getRandomValues } from 'node:crypto', right? In that case, that'd be fine with me, as long as we explicitly say that it's not a use-case we want to support.

Could you maybe explain why we wouldn't expose require('crypto').webcrypto as global.crypto? I'm uncomfortable at the idea of introducing another Node.js specific global, especially if it's competing with one already in browsers and Deno. Is it because REPL (and node --eval) already expose a global-like named crypto and you are concerned it would be too breaking to change that? Sorry if you already discussed that somewhere else, but I feel like I'm missing some context here.

@tniessen
Copy link
Member

Is it because REPL (and node --eval) already expose a global-like named crypto and you are concerned it would be too breaking to change that?

Yes, I think that was the motivation behind #41266 (see #41266 (comment)).

@aduh95
Copy link
Contributor Author

aduh95 commented Feb 11, 2022

FYI, I've opened #41938 to suggest exposing the Web Crypto on the global scope instead of the Node.js one.

@tniessen
Copy link
Member

FYI, I've opened #41938 to suggest exposing the Web Crypto on the global scope instead of the Node.js one.

@aduh95 Now that #41938 has landed, should this be closed or would you still like to remove require('crypto').getRandomValues?

@aduh95
Copy link
Contributor Author

aduh95 commented Feb 16, 2022

would you still like to remove require('crypto').getRandomValues?

I don't think we get much value from having require('crypto').getRandomValues if it's already available (in a web-compatible way) through globalThis.crypto.getRandomValues. I still think we should remove it, or make it web compatible.

should this be closed

Whatever we decide to do we the alias, I think we should land this ASAP: all this PR is doing is documenting that the shortcut is not exactly the same as the web version, and it unblocks #41760.

Currently our docs for Web crypto are "broken", for example here we tell the user to use object destructuring to get a reference to getRandomValues:

node/doc/api/webcrypto.md

Lines 128 to 159 in b8de7aa

### Encryption and decryption
```js
const { subtle, getRandomValues } = require('crypto').webcrypto;
async function aesEncrypt(plaintext) {
const ec = new TextEncoder();
const key = await generateAesKey();
const iv = getRandomValues(new Uint8Array(16));
const ciphertext = await subtle.encrypt({
name: 'AES-CBC',
iv,
}, key, ec.encode(plaintext));
return {
key,
iv,
ciphertext
};
}
async function aesDecrypt(ciphertext, key, iv) {
const dec = new TextDecoder();
const plaintext = await subtle.decrypt({
name: 'AES-CBC',
iv,
}, key, ciphertext);
return dec.decode(plaintext);
}
```

If the user tries to use this code in a browser or Deno, it will throw an arguably quite surprising error (e.g. Chromium throws TypeError: Illegal invocation).

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina
Copy link
Member

@jasnell have you got any concerns in landing this as-is?

@mcollina mcollina removed the tsc-agenda Issues and PRs to discuss during the meetings of the TSC. label Feb 16, 2022
doc/api/crypto.md Outdated Show resolved Hide resolved
@aduh95 aduh95 added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. labels Feb 19, 2022
@aduh95 aduh95 added the review wanted PRs that need reviews. label Feb 19, 2022
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Feb 19, 2022
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

bengl pushed a commit to bengl/node that referenced this pull request Feb 21, 2022
bengl pushed a commit that referenced this pull request Feb 21, 2022
bengl pushed a commit that referenced this pull request Feb 22, 2022
@aduh95 aduh95 merged commit 470c284 into nodejs:master Feb 22, 2022
@aduh95
Copy link
Contributor Author

aduh95 commented Feb 22, 2022

Landed in 470c284

@aduh95 aduh95 deleted the change-getrandomvalues-alias branch February 22, 2022 16:52
sxa pushed a commit to sxa/node that referenced this pull request Mar 7, 2022
@sxa sxa mentioned this pull request Mar 8, 2022
@danielleadams
Copy link
Contributor

@aduh95 this doesn't land cleanly on v16.x-staging. Can you make a backport for this? Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. crypto Issues and PRs related to the crypto subsystem. needs-ci PRs that need a full CI run. review wanted PRs that need reviews.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants