You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
The webcrypto standard (https://w3c.github.io/webcrypto/) is now the official standard for cryptographic operations in browser environments. It is now being supported by all major browsers and electron
As a standardised API, switching over to this API gives us more cross-platform opportunity as the rest of the world's development ecosystem catches up and migrates over to webcrypto standard.
In particular are nativescript and react-native ecosystems. Currently none of them have official crypto APIs, they expect the developer to use underlying native iOS or Android crypto APIs.
It does this through a "webview" trick. Basically this hooks into the browser runtimes that are on iOS and Android to perform the actual crypto and then return the results back to the main application. I have no idea about the performance characteristics of this trick. This trick is described here: https://gun.eco/docs/React-Native and https://github.com/webview-crypto/react-native-webview-crypto
The usage of webcrypto libraries is pioneered by "PeculiarVentures" which has these main libraries:
https://github.com/PeculiarVentures/PKI.js - this could be an alternative to node-forge for all of our PKI/X.509 and TLS related functionality (previously it was claimed this was overly complex compared to node-forge)
https://github.com/PeculiarVentures/webcrypto - this is a generic polyfill for webcrypto, not entirely sure how it wraps the native webcrypto inside nodejs or if smooths over the differences, there is a discussion about this library in relation to other webcrypto polyfills targeting nodejs https://github.com/PeculiarVentures/webcrypto, because this is also mentioned with respect to the webview trick, there may also be a relationship between the webview trick and this polyfill
They have many other crypto related libraries that we should investigate
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.
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.
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:
Uint8ArrayandArrayBufferwhich can help us standardise our buffer usage across js-db, js-id, js-workers and more, especially as workers requireArrayBufferto do zero-copynode-forgesource code isn't well maintained and doesn't have as many eyes watching and evaluating its securityNow for some background:
This comment #43 (comment) explains how we came to be using
node-forgeas 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
networkingdomain such as utp-native.Here are something I found that may be relevant to us proceeding here:
node-forge)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
keysdomain abstracts over most(all?) crypto operations for all other domains. Except in the case of EFS which is currently pinned tonode-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
bufferWrapto supportArrayBuffer,Uint8ArrayandBufferjs-db#3 - can help make use of the migration toArrayBufferand typed arraysWasmer 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