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

Implement webcrypto APIs. #1891

Closed
afinch7 opened this issue Mar 6, 2019 · 38 comments
Closed

Implement webcrypto APIs. #1891

afinch7 opened this issue Mar 6, 2019 · 38 comments
Labels
feat new feature (which has been agreed to/accepted) web related to Web APIs

Comments

@afinch7
Copy link
Contributor

afinch7 commented Mar 6, 2019

Some applications like handling password will require hashing and encryption. These operations could be implemented in js/ts, but It really needs to be handled from a trusted environment to be secure. It looks like there have been some attempts to get this one rolling before recently with #1461.

@dsseng
Copy link
Contributor

dsseng commented Apr 17, 2019

Classical method: new Rust ops, TS frontend for them and testing. Will take a look at, maybe work on.

@anjmao
Copy link

anjmao commented Sep 27, 2019

Maybe this repo will be useful for examples https://github.com/diafygi/webcrypto-examples of the usage.

Chromium's implementation of WebCrypto source code https://chromium.googlesource.com/chromium/src/+/master/components/webcrypto/

Are you planning to implement all algorithms in Rust or use already provided community packages? I would suggest to link existing source code written in C++ from chromium since it may not be a good idea to use some Rust package which is not well maintained and wasn't reviewed by security experts.

@dsseng
Copy link
Contributor

dsseng commented Sep 27, 2019

We could use Chromium code, but it can be difficult to integrate

@chiefbiiko
Copy link
Contributor

Related: denoland/deno_std Add crypto module #48

IMHO, implementing the webcrypto API is not the most pressing thing to do regarding deno & crypto.

What I don't like about webcrypto:

  • unnecessary and confusing API surface (Crypto, SubtleCrypto, etc.)
  • supports various obsolete algorithms, hardly state-of-the-art
  • the primary SubtleCrypto interface is a pretty low-level API, inviting users to mix-n-match

🦕 ❤️🔐 = I would love to see deno expose a high-level, hard-to-misuse, modern crypto API like libsodium. No need for obsolete stuff, e.g. SHA1, PBKDF2, RSASSA-PKCS1-v1_5. That can be done in userland if needed. deno should exclusively focus on providing high-security, state-of-the-art crypto with a simple API. Of course, browser compat...

Do we need sth like a nursery repo (denoland/deno_nursery/crypto)?

@kitsonk
Copy link
Contributor

kitsonk commented Sep 29, 2019

Something usable should be in deno_std on top of the web compatible stuff.

Also, we already have precedence for not supporting obsolete things, like TextDecorder() which only supports utf8.

Nurseries are hard to manage, people end up using them, not respecting that they aren't "production ready" and then it becomes a defacto things. Iterating on something in deno_std built on top of the web standard APIs is really the best idea. The parts of the web standard really should be implemented directly in Rust too for both security and performance.

@samuelgozi
Copy link

samuelgozi commented Apr 29, 2020

I think Crypto should be a higher priority.
Every server-side application that handles authentication will need to be able to verify/sign data.
All major cloud providers give authorization in the form of private keys/JWTs.

I ported Firebase firestore and storage libraries but didn't publish them because without being able to sign and verify with RSASSA-PKCS1-V1_5 there is nothing they can really do(unless used as a regular client).

@sejr
Copy link

sejr commented May 14, 2020

Also worth considering is the crypto package from Go's standard library: https://golang.org/pkg/crypto/

I think the ideal approach would be a blend of that package and the subtle interface that is expected in the browser context.

I have a very early effort to implement the SubtleCrypto interface in a deno crypto playground. Curious if there are any others interested in collaborating.

Generally speaking, I think the project could benefit from "working groups," whether it's something formal or just additional channels in the Discord.

@ekanna
Copy link

ekanna commented May 14, 2020

Related: denoland/deno_std Add crypto module #48

IMHO, implementing the webcrypto API is not the most pressing thing to do regarding deno & crypto.

What I don't like about webcrypto:

  • unnecessary and confusing API surface (Crypto, SubtleCrypto, etc.)
  • supports various obsolete algorithms, hardly state-of-the-art
  • the primary SubtleCrypto interface is a pretty low-level API, inviting users to mix-n-match

🦕 ❤️🔐 = I would love to see deno expose a high-level, hard-to-misuse, modern crypto API like libsodium. No need for obsolete stuff, e.g. SHA1, PBKDF2, RSASSA-PKCS1-v1_5. That can be done in userland if needed. deno should exclusively focus on providing high-security, state-of-the-art crypto with a simple API. Of course, browser compat...

Do we need sth like a nursery repo (denoland/deno_nursery/crypto)?

If you follow "Web Crypto API" it works every where without any dependencies. Eg. Browser, Edge Computing Networks (like Cloudflare workers, AWS Lambda, Google cloud functions). Currently testing this edge code is not easy. With Deno one can test this code locally without much effort.

"Web Crypto API" feature is a must have. After all, they have already implemented everything else. Why to leave this alone?

@jdanyow
Copy link

jdanyow commented May 16, 2020

One of Deno's primary appeals is symmetry with the web and Cloudflare workers. I agree with much of @chiefbiiko's comment, however I ask that the developer cost of diverging the API surface from the web be considered in this decision.

@gjolund
Copy link

gjolund commented Jun 8, 2020

What is the current state of crypto on deno?

I am interested in this project due to its emphasis on a std library, and it seems like crypto would be a core part of that effort.

Currently in deno there is no way to generate a jwks or similar crypto artifacts, meaning that I have to rely on the host system and pass around key files.

Is there something I am missing or is that the current best practice?

@sejr
Copy link

sejr commented Jun 8, 2020 via email

@kitsonk
Copy link
Contributor

kitsonk commented Jun 8, 2020

I don't think there is much of a debate... As the title of the issues says... Implement the web crypto APIs. There would be no issue with implementing Web Crypto APIs beyond the .getRandomValues() which is already implemented.

@gjolund
Copy link

gjolund commented Jun 10, 2020

@kitsonk @sejr thanks for the reply, sorry if my comment came across as demanding.

Please correct me if I am expanding the scope of the stdlib beyond deno's intentions, but in order to avoid the dependency bloat seen in npm I think that more is required than just the base web crypto apis.

For example in order to implement a jwks or any feature relying on JOSE deno would need node crypto to be ported along with jose support for the following specs.

JSON Web Signature (JWS) - RFC7515
JSON Web Encryption (JWE) - RFC7516
JSON Web Key (JWK) - RFC7517
JSON Web Algorithms (JWA) - RFC7518
JSON Web Token (JWT) - RFC7519
JSON Web Key Thumbprint - RFC7638
JWS Unencoded Payload Option - RFC7797
CFRG Elliptic Curve ECDH and Signatures - RFC8037
secp256k1 EC Key curve support - JOSE Registrations for WebAuthn Algorithms

Packages like npm jose have basically become a part of the nodejs core due to their almost ubiquitous usage and strict adherence to IETF specs.

Perhaps this will start out as a community package, however its seems likely that this would just result in multiple implementations with varying levels of correctness, which is a recipe for disaster when it comes to crypto.

I would like to contribute to this effort, as I see strong crypto support being the major blocker for deno that prevents me from considering it for serious applications.

@kitsonk
Copy link
Contributor

kitsonk commented Jun 10, 2020

@austinrivas I didn't take it that way. My comment was more directed at @sejr. Implementing the Web Crypto APIs in Deno is something that should be done and wouldn't be controversial. They don't really offer good higher order solutions though. Outside of basic primitives though, they should likely be a community project.

That being said, JWT, JWS, JWK, etc. are "standard" enough (and important enough to have provably correct implementations), that they might be good targets for std inclusion built upon the low level Web Crypto APIs.

@sejr
Copy link

sejr commented Jun 10, 2020

Apologies, my reply was poorly worded. I definitely agree (as do most I’ve discussed with) about the priority for WebCrypto.

From those discussions, here and on Discord, it seemed like there was not yet a decision when it comes to building the backend for these APIs in pure Rust vs. linking to existing code in V8. Would love to hear your thoughts on that @kitsonk.

I think the JWT/S/K implementations would be a good start too. Worth noting existing work in this package: https://deno.land/x/djwt/README.md

@sayore
Copy link

sayore commented Aug 19, 2020

Has this been lost in discussion? Seems kinda important for security, and will be a gamechanger for people who want to use deno(and implement oauth & alikes); or am i missing the point of crypto libaries?

Edit: I am not trying to be pushy, especially as a non-contributor. I just wanted to push this up if possible.

@panva
Copy link
Contributor

panva commented Sep 28, 2020

I think the JWT/S/K implementations would be a good start too.

With the advent of WebCrypto API in Node.js my jose module will become an ESM module utiling it. It covers all of JW[STEAK] and would immediately work in Deno too if it got support for WebCrypto.

@kitsonk kitsonk added web related to Web APIs feat new feature (which has been agreed to/accepted) labels Nov 5, 2020
@ssslambda
Copy link

ssslambda commented Nov 24, 2020

Any updates?.. I just would to hash passwords without 3rd party modules, is it too much to ask for?.. (Sorry for irony)

@bartlomieju bartlomieju mentioned this issue Dec 18, 2020
22 tasks
@aral
Copy link

aral commented Dec 20, 2020

Please consider including the Curve25519 algorithms in the implementation.

https://www.chromestatus.com/feature/4913922408710144

@yacinehmito
Copy link
Contributor

@kitsonk Which crypto library should we rely on? I probed a bit and, from my limited knowledge, the only library with an up-to-date Rust crate that covers the whole scope of the Web Crypto API would be OpenSSL. However, including OpenSSL in Deno seems to significantly the build complexity.

I can scaffold the code to expose the Web Crypto API but I'd need direction on which underlying implementation we should rely on.

@lucacasonato
Copy link
Member

We can likely use ring for most crypto operations. It is already in our dependency tree through rustls. See https://briansmith.org/rustdoc/ring/

@yacinehmito
Copy link
Contributor

yacinehmito commented Jan 4, 2021

Unfortunately ring does not support RSA key generation, but it's part of the Web Crypto API.
See briansmith/ring#219 and briansmith/ring#733.

@mimiza
Copy link

mimiza commented Jan 24, 2021

If WebCrypto is supported, I will immediately move my projects to Deno.

@gjolund
Copy link

gjolund commented Jan 26, 2021

If WebCrypto is supported, I will immediately move my projects to Deno.

Agreed, this is the one must have feature that I am waiting for in order to start using deno seriously.

@pitust
Copy link

pitust commented Feb 24, 2021

I mean, there are wasm-powered libsodium bindings

@lucacasonato
Copy link
Member

Simplified your example using async await:

const encoder = new TextEncoder();
const data = encoder.encode("January February");

const algorithm = { name: "AES-CBC", iv: encoder.encode("0123456789ABCDEF") };
const key = await crypto.subtle.importKey("raw", encoder.encoder("GHIJKLMNOPQRSTUV"), "AES-CBC", true, ["encrypt"]);
const encryptedData = await crypto.subtle.encrypt(algorithm, key, data);
console.log(encryptedData);

I would argue that the SubtleCrypto API is a lot more customizable than for example PHP. You can adjust a whole bunch of parameters. For example you can encrypt raw bytes, not just strings, and you have a far wider range of keys types and encryption algorithms to choose from.

@lucacasonato
Copy link
Member

Feel free to open an issue with the spec: https://github.com/w3c/webcrypto :-)

@hayd
Copy link
Contributor

hayd commented Mar 19, 2021

Common usecases/boilerplate can be a library (or potentially even in std) on top of SubtleCrypto.

@lucacasonato
Copy link
Member

@89z One obvious difference is that node crypto is not async. This issue is about webcrypto implementation in Deno, not about comparing all the different crypto implementations. If you want to chat about this further please hop on Discord: https://discord.gg/deno.

The decision to implement SubtleCrypto in Deno has been made. It will happen.

@benatkin
Copy link

benatkin commented Mar 22, 2021

Some options:

  • https://deno.land/std@0.91.0/node/crypto.ts - doesn't have createCipherIv, has good code reviewing
  • https://deno.land/x/crypto - 4 stars. might be on the right path but needs more engagement. author doesn't have a lot of followers yet. author seems active and open to contributions. I'm starring and following.
  • https://deno.land/x/sodium - 14 stars. part of the denosaurs project, which is unofficial but has a lot of stars on some projects. would prefer more reviewing of the code and the publish process but the underlying library is well-reviewed.

@iugo
Copy link
Contributor

iugo commented Mar 23, 2021

I hope to be as consistent as possible with the browser.

MDN: https://developer.mozilla.org/en-US/docs/Web/API/Crypto

@stagas
Copy link

stagas commented May 4, 2021

Another (temporary) solution:

import { crypto } from 'https://cdn.skypack.dev/@stagas/webcrypto-liner'

is a fork of webcrypto-liner which implements WebCrypto in TS/JS -- not all APIs work but some do - mainly I used crypto.subtle.importKey and crypto.subtle.sign with success so I'm posting it here in case it's useful to someone.

The fork simply fixes a couple of compatibility issues when using deno deploy. Theoretically the library can be ported to deno entirely but it's too many components involved so it takes some time investment to do it.

@timreichen
Copy link
Contributor

timreichen commented Jul 21, 2021

@panva would you be interested in creating a draft with me for std that includes jws and jwt for a start now that webcrypto is partially supported? (discord timreichen#1717)

@panva
Copy link
Contributor

panva commented Jul 21, 2021

@panva would you be interested in creating a draft with me for std that includes jws and jwt for a start now that webcrypto is partially supported? (discord timreichen#1717)

Sure, you can reach out to me on the OpenJS Foundation slack.

@bartlomieju
Copy link
Member

Many Web Crypto APIs are already supported in Deno. Let's continue in #11690

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat new feature (which has been agreed to/accepted) web related to Web APIs
Projects
None yet
Development

No branches or pull requests