mirror of https://github.com/waku-org/js-waku.git
Add encryption/signature documentation
This commit is contained in:
parent
455b568cde
commit
4f796ab920
|
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
### Added
|
### Added
|
||||||
- Examples (web-chat): New `/fleet` command to switch connection between Status prod and test fleets.
|
- Examples (web-chat): New `/fleet` command to switch connection between Status prod and test fleets.
|
||||||
- Export `generatePrivateKey` and `getPublicKey` directly from the root.
|
- Export `generatePrivateKey` and `getPublicKey` directly from the root.
|
||||||
|
- Usage of the encryption and signature APIs to the readme.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- **Breaking**: Renamed `WakuRelay.(add|delete)PrivateDecryptionKey` to `WakuRelay.(add|delete)DecryptionKey` to make it clearer that it accepts both symmetric keys and asymmetric private keys.
|
- **Breaking**: Renamed `WakuRelay.(add|delete)PrivateDecryptionKey` to `WakuRelay.(add|delete)DecryptionKey` to make it clearer that it accepts both symmetric keys and asymmetric private keys.
|
||||||
|
|
128
README.md
128
README.md
|
@ -117,6 +117,134 @@ waku.store.queryHistory({
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Encryption & Signature
|
||||||
|
|
||||||
|
With js-waku, you can:
|
||||||
|
|
||||||
|
- Encrypt messages over the wire using public/private key pair (asymmetric encryption),
|
||||||
|
- Encrypt messages over the wire using a unique key to both encrypt and decrypt (symmetric encryption),
|
||||||
|
- Sign and verify your waku messages (must use encryption, compatible with both symmetric and asymmetric).
|
||||||
|
|
||||||
|
### Cryptographic Libraries
|
||||||
|
|
||||||
|
A quick note on the cryptographic libraries used as it is a not a straightforward affair:
|
||||||
|
- Asymmetric encryption: Uses [ecies-geth](https://github.com/cyrildever/ecies-geth/) which in turns uses [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) Web API (browser), [secp256k1](https://www.npmjs.com/package/secp256k1) (native binding for node) or [elliptic](https://www.npmjs.com/package/elliptic) (pure JS if none of the other libraries are available).
|
||||||
|
- Symmetric encryption: uses [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) Web API (browser) or [NodeJS' crypto](https://nodejs.org/api/crypto.html) module. Which means there is no fallback if [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) is not available, [elliptic](https://www.npmjs.com/package/elliptic) could be added if the need rises.
|
||||||
|
|
||||||
|
### Create new keys
|
||||||
|
|
||||||
|
Asymmetric private keys and symmetric keys are expected to be 32 bytes arrays.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { generatePrivateKey, getPublicKey } from 'js-waku';
|
||||||
|
|
||||||
|
// Asymmetric
|
||||||
|
const privateKey = generatePrivateKey();
|
||||||
|
const publicKey = getPublicKey(privateKey);
|
||||||
|
|
||||||
|
// Symmetric
|
||||||
|
const symKey = generatePrivateKey();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Encrypt Waku Messages
|
||||||
|
|
||||||
|
To encrypt your waku messages, simply pass the encryption key when creating it:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { WakuMessage } from 'js-waku';
|
||||||
|
|
||||||
|
// Asymmetric
|
||||||
|
const message = await WakuMessage.fromBytes(payload, {
|
||||||
|
contentTopic: myAppContentTopic,
|
||||||
|
encPublicKey: publicKey,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Symmetric
|
||||||
|
const message = await WakuMessage.fromBytes(payload, {
|
||||||
|
contentTopic: myAppContentTopic,
|
||||||
|
symKey: symKey,
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Decrypt Waku Messages
|
||||||
|
|
||||||
|
#### Waku Relay
|
||||||
|
|
||||||
|
If you expect to receive encrypted messages then simply add private decryption key(s) to `WakuRelay`.
|
||||||
|
Waku Relay will attempt to decrypt incoming messages with each keys, both for symmetric and asymmetric encryption.
|
||||||
|
Messages that are successfully decrypted (or received in clear) will be passed to the observers, other messages will be ommitted.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// Asymmetric
|
||||||
|
waku.relay.addDecryptionKey(privateKey);
|
||||||
|
|
||||||
|
// Symmetric
|
||||||
|
waku.relay.addDecryptionKey(symKey);
|
||||||
|
|
||||||
|
// Then add the observer
|
||||||
|
waku.relay.addObserver(callback, [contentTopic]);
|
||||||
|
```
|
||||||
|
|
||||||
|
Keys can be removed using `WakuMessage.deleteDecryptionKey`.
|
||||||
|
|
||||||
|
#### Waku Store
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const messages = await waku.store.queryHistory({
|
||||||
|
contentTopics: [],
|
||||||
|
decryptionKeys: [privateKey, symKey],
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Similarly to relay, only decrypted or clear messages will be returned.
|
||||||
|
|
||||||
|
### Sign Waku Messages
|
||||||
|
|
||||||
|
As per version 1`s [specs](https://rfc.vac.dev/spec/26/), signatures are only included in encrypted messages.
|
||||||
|
In the case where your app does not need encryption then you could use symmetric encryption with a trivial key, I intend to dig [more on the subject](https://github.com/status-im/js-waku/issues/74#issuecomment-880440186) and come back with recommendation and examples.
|
||||||
|
|
||||||
|
Signature keys can be generated the same way asymmetric keys for encryption are:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { generatePrivateKey, getPublicKey, WakuMessage } from 'js-waku';
|
||||||
|
|
||||||
|
const signPrivateKey = generatePrivateKey();
|
||||||
|
|
||||||
|
// Asymmetric Encryption
|
||||||
|
const message = await WakuMessage.fromBytes(payload, {
|
||||||
|
contentTopic: myAppContentTopic,
|
||||||
|
encPublicKey: recipientPublicKey,
|
||||||
|
sigPrivKey: signPrivateKey
|
||||||
|
});
|
||||||
|
|
||||||
|
// Symmetric Encryption
|
||||||
|
const message = await WakuMessage.fromBytes(payload, {
|
||||||
|
contentTopic: myAppContentTopic,
|
||||||
|
encPublicKey: symKey,
|
||||||
|
sigPrivKey: signPrivateKey
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verify Waku Message signatures
|
||||||
|
|
||||||
|
Two fields are available on `WakuMessage` regarding signatures:
|
||||||
|
|
||||||
|
- `signaturePublicKey`: If the message is signed, it holds the public key of the signature,
|
||||||
|
- `signature`: If the message is signed, it holds the actual signature.
|
||||||
|
|
||||||
|
Thus, if you expect messages to be signed by Alice,
|
||||||
|
you can simply compare `WakuMessage.signaturePublicKey` with Alice's public key.
|
||||||
|
As comparing hex string can lead to issues (is the `0x` prefix present?),
|
||||||
|
simply use helper function `equalByteArrays`.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { equalByteArrays } from 'js-waku/lib/utils';
|
||||||
|
|
||||||
|
const sigPubKey = wakuMessage.signaturePublicKey;
|
||||||
|
|
||||||
|
const isSignedByAlice = sigPubKey && equalByteArrays(sigPubKey, alicePublicKey);
|
||||||
|
```
|
||||||
|
|
||||||
## More documentation
|
## More documentation
|
||||||
|
|
||||||
Find more [examples](#examples) below
|
Find more [examples](#examples) below
|
||||||
|
|
Loading…
Reference in New Issue