Skip to content

Migrating/Integrating WebCrypto (possibly WASM) instead of Node Forge Crypto #270

@CMCDragonkai

Description

@CMCDragonkai

Specification

The work in #155 involving nativescript meant that we are starting to consider alternatives to Node forge crypto in order to standardise our crypto API and future proof to future JS-based platforms. There are number of reasons to look into webcrypto:

  • WebCrypto is a standard across ES platforms, thus enabling more potential native-implementations which can improve performance and security (prevent timing attacks)
  • WebCrypto API focuses on using ES-compliant buffers like Uint8Array and ArrayBuffer which can help us standardise our buffer usage across js-db, js-id, js-workers and more, especially as workers require ArrayBuffer to do zero-copy
  • There is existing work with WebCrypto API involving WASM to plug in functionality that isn't supported by the standard, such as providing ed25519 keys, and this will help us resolve the usage of ed25519 Replace node-forge RSA Keypair With ed25519/x25519 Keypair #168
  • The node-forge source code isn't well maintained and doesn't have as many eyes watching and evaluating its security

Now for some background:

This comment #43 (comment) explains how we came to be using node-forge as opposed to other cryptographic libraries.

I know that when Polykey project first started, we initially were thinking of using PGP and thus the kbpgp.js library (https://github.com/keybase/kbpgp). We ended up going away from PGP due to its limited usage in a number of scenarios that we want PK to deal with. Namely end to end encrypted network communication which is a TLS issue, that makes use of X.509 certificates rather than PGP certificates. Furthermore we also had symmetric encryption/decryption scenarios like js-encryptedfs that again would not make use of PGP standards. Therefore it just lacked interoperability with many other cryptographic scenarios, it seemed like its own island of standards, the library can still be brought back in in the future if we find usecases for PK using PGP.

However in choosing node-forge, we came across a few other problems. Mainly overall-cross platform compatibility planning for mobile devices. This is not just a problem with crypto, but also other libraries that are used in our networking domain such as utp-native.

Here are something I found that may be relevant to us proceeding here:

All of this will mean that we either replace node-forge, or end up creating a adapter pattern where we plugin different crypto implementions depending on our environment. At this point in time, the keys domain abstracts over most(all?) crypto operations for all other domains. Except in the case of EFS which is currently pinned to node-forge (it may be a good idea to abstract that and expect an interface of functions for EFS).

Cross platform compatibility here isn't just about the fundamental crypto library. It's also about other parts of PK. One closely related situation is the JOSE libraries. As they involve cryptographic operations, they currently seem to "fix" their underlying crypto library as well. It would be ideal that if we standardise on a crypto library for cross-platform deployment, that we can also ensure that our JOSE library is using the same crypto library to reduce our crypto attack surface. We are currently using https://github.com/panva/jose which uses native crypto depending on the platform including webcrypto. Contenders include https://github.com/cisco/node-jose (which fixes on node-forge) and https://github.com/square/js-jose.

Additional context

Wasmer can compile WASM code to native code. But wasm3 is for interpretation. Why use interpetation?

It appears that in some cases interpretation can be more widely deployed. There are examples of iOS apps using wasm3. https://github.com/kateinoigakukun/wasmic-ios

It's becoming fast a standard target for many languages. Even TypeScript when ported to AssemblyScript can be compiled to WASM.

Once it is WASM, the only thing missing is broad adoption of WASI. If WASI is broadly adopted like it is in nodejs (https://github.com/nodejs/uvwasi), then pretty much we have a universal portable binary capable of doing relevant system operations. WASI is like a universal standard of system calls. Like a whole new POSIX standard.

Then one would just use WASM and WASI for all platforms.

Tasks

  1. ...
  2. ...
  3. ...

Metadata

Metadata

Assignees

Labels

developmentStandard developmentepicBig issue with multiple subissuesr&d:polykey:core activity 2Cross Platform Cryptography for JavaScript Platforms

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions