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

Streams for the Web Cryptography API #637

Closed
tniessen opened this issue May 14, 2022 · 6 comments
Closed

Streams for the Web Cryptography API #637

tniessen opened this issue May 14, 2022 · 6 comments
Labels
position: neutral venue: W3C CG Specifications in W3C Community Groups (e.g., WICG, Privacy CG)

Comments

@tniessen
Copy link

Request for Mozilla Position on an Emerging Web Specification

Other information

This specification is in a very early state. The effort is driven by the @wintercg, a new W3C Community Group. We are posting this so that Mozilla is aware of the proposal and in the hope that Mozilla would consider implementing such an extension.

@martinthomson
Copy link
Member

The specification is pretty scant currently, so it is probably premature to seek feedback.

I will say, based on reading the explainer, this seems like an effort to build a more powerful footgun. Of the proposed changes, the use of streams in digest is the only one that I can endorse without reservation. For the others, a streaming encryption that only works outside of authenticated modes would only seem to encourage bad practices. Signing is probably OK; modes that are effectively a hash followed by a signature are a good candidate for this (as noted: all those currently specified), but there is a reason that Ed25519ph/Ed448ph are not widely implemented.

All that said, the whole point of crypto.subtle is to build a giant footgun. As this is consistent with that goal, this seems broadly OK.

@annevk annevk added the venue: W3C CG Specifications in W3C Community Groups (e.g., WICG, Privacy CG) label May 16, 2022
@tniessen
Copy link
Author

Thank you for the feedback @martinthomson!

For the others, a streaming encryption that only works outside of authenticated modes would only seem to encourage bad practices.

This is one of our main concerns as well, and we might end up removing EncryptionStream and DecryptionStream if it makes adoption of the spec more likely (cc @twiss who suggested it might).

All that said, the whole point of crypto.subtle is to build a giant footgun. As this is consistent with that goal, this seems broadly OK.

I am not exactly a fan of the Web Cryptography API myself, but I am also not aware of a better mechanism for doing cryptographic operations in a browser that would not result in side-channel vulnerabilities.

@martinthomson
Copy link
Member

Discussed with a few folks today. Overall, we're going with non-harmful. This won't show up on the dashboard.

There were concerns about the overloading of the API to accept (and produce!) streams in places where we would have accepted/provided BufferSource/ArrayBuffer. This is probably most noticeable for crypto.subtle.encrypt, which produces a stream as output. It might be better for these to use a different function in some of these cases. This view was tempered partly by virtue of the fact that WebCrypto is already a mess of overloading.

@sukima
Copy link

sukima commented Dec 6, 2024

I can understand peoples reservations in this regard but from a JS Dev's perspective I can say that is not good enough. The simple ask is this: As a JavaScript developer who is writing a browser based application I want to encrypt/decrypt large data.

There are only two solutions to this and both have issues. The browser can offer them a TransformStream that they can use or the JS Developer can chunk the data themselves manually and encrypt/decrypt the chunks individually.

The browsers currently do not offer a secure/safe TransformStream for this task which means the only option is to chunk the data manually. A quick web search on how to chunk data for encryption use reveals an almost indigestible amount of NEVER DO THIS panic. We shall never roll our own use of crypto they say. Even if one were to push through the not-smart-enough-gate-keeping there is almost no literature I can find that shows how to properly chunk/encode such a stream.

I beg you, as a non-woring-group member, please don't dismiss this proposal. Please understand there is a definitive and real use case for encrypting/decrypting large data. If it is not possible to do so via the crypto.subtle API then at least offer a definitive explanation on how developers can copy/paste/write their own TransformStream that will correctly chunk large data.

@sukima
Copy link

sukima commented Dec 6, 2024

Another use case is that any data that is to be compressed then encrypted requires converting data to a stream then back to data to encrypt/decrypt. This is orthogonal to the idea of streams where you can pipe the processes. It is strange and awkward.

await reader
  .pipeThrough(new CompressionStream('deflate-raw'))
  .pipeThrough(new EncryptStream(..., 'password'))
  .pipeTo(socketWriter);

That just makes sense compared to:

const collectedData = new CollectionWriter();
await reader.pipeThrough(new CompressionStream('deflate-raw')).pipeTo(collectedData);
const ciphertext = await encrypt(collectedData.result, ..., 'password');
ReadableStream.from(ciphertext).pipeTo(socketWriter);

How can we do the first one safely, securely, correctly, and maybe without scorn?

@twiss
Copy link

twiss commented Dec 6, 2024

@sukima This feature is being discussed in w3c/webcrypto#73. Nobody is dismissing that use case per se; this issue being closed just means that Mozilla has landed on a standards position. Though, from the standardization side I'll probably focus on streaming hashing first since that's less controversial and has fewer footguns.

In the meantime, you could use something like https://github.com/dchest/nacl-stream-js; it should be fairly simple to write a TransformStream wrapper around that, I think.

In fact, "don't roll your own crypto" doesn't mean that it has to be implemented in the browser, specifically, although that does have some advantages. But using a vetted library is a perfectly fine alternative to comply with that adage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
position: neutral venue: W3C CG Specifications in W3C Community Groups (e.g., WICG, Privacy CG)
Projects
None yet
Development

No branches or pull requests

5 participants