waku-org / js-waku

JavaScript implementation of Waku v2
https://js.waku.org
Apache License 2.0
171 stars 42 forks source link

Provide an API to use `crypto.subtle` for `SymEncoder` and `AsymEncoder` #984

Open filoozom opened 2 years ago

filoozom commented 2 years ago
This is a **feature request** ## Problem

Right now, SymEncoder uses a Uint8Array key to sign messages and encrypt them. It uses secp256k1 and nothing else can be used. This is a perfectly valid choice and I'm not sure it's worth it making the API more complicated as we already have sane defaults. However, in our case we were already using crypto.subtle, and it turns out that those keys cannot be used with SymEncoder.

Two issues:

Proposed Solutions

Instead of passing a private key directly, it might be more appropriate to pass some object that contains sign and publicKey properties for the signing, and another object that has an encrypt function for the encryption.

For example, instead of:

new SymEncoder(
    'topic',
    encryptionKey,
    signingKey
)

have something like:

const encryptionKey = await crypto.subtle.deriveKey(/* ECDH */)
const signingKey = await crypto.subtle.generateKey(/* ECDSA */)

new SymEncoder(
    'topic',
    {
        encrypt: async (data: Uint8Array) => crypto.subtle.encrypt(algorithm, encryptionKey, data)
    },
    {
        sign: async (data: Uint8Array) => crypto.subtle.sign(algorithm, signingKey, data),
        publicKey: Uint8Array
    }
)

Alternatively, it would be quite useful to document the algorithms that are used here: https://js.waku.org/classes/lib_waku_message_version_1.SymEncoder.html

I know I should have read the RFC and maybe dived into the code a bit more, but as someone who is not that familiar with cryptography, I wasn't aware that P-256 was different from secp256k1 for example. In hindsight it seems fairly obvious, but I guess I was a bit too naïve. 😅

Notes

From what I can see secp256k1 is the only curve supported by the RFC (https://rfc.vac.dev/spec/26/), so this might be more trouble than it's worth. For now, I'm just going to change everything and get rid of crypto.subtle in order to implement something closer to the eth-pm example.

fryorcraken commented 2 years ago

Relevant https://github.com/w3c/webcrypto/issues/82#issuecomment-849856773

fryorcraken commented 2 years ago

While it doesn't seem we can use Subtle Crypto for Waku Message 1 cryptographic operations, I think it could be interested to define a new standard that uses modern schemes available in Subtle Crypto to provide a more secure turn key solution for encryption and signing purposes.

fryorcraken commented 1 year ago

Do note that the direction we are currently going towards for encryption is https://rfc.vac.dev/spec/35/ but this does not help for signing.