From 15612cbfbd9dcbddddbf3000eea7de2f7582e78d Mon Sep 17 00:00:00 2001 From: LordGhostX Date: Wed, 6 Dec 2023 05:54:28 +0100 Subject: [PATCH 01/12] add symmetric and ECIES encryption --- docs/guides/js-waku/index.md | 1 + docs/guides/js-waku/light-send-receive.md | 2 +- docs/guides/js-waku/manage-filter.md | 2 +- docs/guides/js-waku/message-encryption.md | 127 ++++++++++++++++++++++ docs/learn/waku-network.md | 8 +- docusaurus.config.js | 4 + sidebars.js | 1 + 7 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 docs/guides/js-waku/message-encryption.md diff --git a/docs/guides/js-waku/index.md b/docs/guides/js-waku/index.md index 47f71d57..066d6cce 100644 --- a/docs/guides/js-waku/index.md +++ b/docs/guides/js-waku/index.md @@ -85,6 +85,7 @@ Have a look at the quick start guide and comprehensive tutorials to learn how to | - | - | | [Send and Receive Messages Using Light Push and Filter](/guides/js-waku/light-send-receive) | Learn how to send and receive messages on light nodes using the [Light Push](/learn/concepts/protocols#light-push) and [Filter](/learn/concepts/protocols#filter) protocols | | [Retrieve Messages Using Store Protocol](/guides/js-waku/store-retrieve-messages) | Learn how to retrieve and filter historical messages on light nodes using the [Store protocol](/learn/concepts/protocols#store) | +| [Encrypt and Decrypt Your Waku Messages](/guides/js-waku/message-encryption) | Learn how to use the [@waku/message-encryption](https://www.npmjs.com/package/@waku/message-encryption) package to encrypt and decrypt your messages | | [Build React DApps Using @waku/react](/guides/js-waku/use-waku-react) | Learn how to use the [@waku/react](https://www.npmjs.com/package/@waku/react) package seamlessly integrate `@waku/sdk` into a React application | | [Scaffold DApps Using @waku/create-app](/guides/js-waku/use-waku-create-app) | Learn how to use the [@waku/create-app](https://www.npmjs.com/package/@waku/create-app) package to bootstrap your next `@waku/sdk` project from various example templates | | [Bootstrap Nodes and Discover Peers](/guides/js-waku/configure-discovery) | Learn how to bootstrap your node using [Static Peers](/learn/concepts/static-peers) and discover peers using [DNS Discovery](/learn/concepts/dns-discovery) | diff --git a/docs/guides/js-waku/light-send-receive.md b/docs/guides/js-waku/light-send-receive.md index 7cbb7287..fd52bc36 100644 --- a/docs/guides/js-waku/light-send-receive.md +++ b/docs/guides/js-waku/light-send-receive.md @@ -128,7 +128,7 @@ const callback = (wakuMessage) => { console.log(messageObj); }; -// Create a filter subscription +// Create a Filter subscription const subscription = await node.filter.createSubscription(); // Subscribe to content topics and process new messages diff --git a/docs/guides/js-waku/manage-filter.md b/docs/guides/js-waku/manage-filter.md index 0feafff1..1019b9fc 100644 --- a/docs/guides/js-waku/manage-filter.md +++ b/docs/guides/js-waku/manage-filter.md @@ -3,7 +3,7 @@ title: Manage Your Filter Subscriptions hide_table_of_contents: true --- -This guide provides detailed steps to manage [Filter](/learn/concepts/protocols#filter) subscriptions and handle node disconnections in your application. Have a look at the [Filter guide](/guides/js-waku/light-send-receive) for receiving messages with the `Light Push` and `Filter` protocol. +This guide provides detailed steps to manage [Filter](/learn/concepts/protocols#filter) subscriptions and handle node disconnections in your application. Have a look at the [Send and Receive Messages Using Light Push and Filter](/guides/js-waku/light-send-receive) guide for using the `Light Push` and `Filter` protocols. ## Overview diff --git a/docs/guides/js-waku/message-encryption.md b/docs/guides/js-waku/message-encryption.md new file mode 100644 index 00000000..9b1c21eb --- /dev/null +++ b/docs/guides/js-waku/message-encryption.md @@ -0,0 +1,127 @@ +--- +title: Encrypt and Decrypt Your Waku Messages +hide_table_of_contents: true +--- + +This guide provides detailed steps to use the [@waku/message-encryption](https://www.npmjs.com/package/@waku/message-encryption) package to encrypt and decrypt your messages using [Waku message payload encryption](/learn/glossary#waku-message-payload-encryption) methods. + +:::info +Waku lacks protocol-level message encryption because it does not know the communication parties. This design choice enhances Waku's encryption flexibility, encouraging developers to freely use custom protocols or [Waku message payload encryption](/learn/glossary#waku-message-payload-encryption) methods. +::: + +## Installation + +Install the `@waku/message-encryption` package using your preferred package manager: + +```mdx-code-block +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; +``` + + + + +```shell +npm install @waku/message-encryption +``` + + + + +```shell +yarn add @waku/message-encryption +``` + + + + +## Symmetric encryption + +Symmetric encryption uses a single, shared key for message encryption and decryption. Use the `generateSymmetricKey()` function to generate a random symmetric key: + +```js +import { generateSymmetricKey } from "@waku/message-encryption"; + +// Generate a random symmetric key +const symKey = generateSymmetricKey(); +``` + +To send encrypted messages, create a symmetric message `encoder` and send the message as usual: + +```js +import { createEncoder } from "@waku/message-encryption/symmetric"; + +// Create a symmetric message encoder +const encoder = createEncoder({ + contentTopic: contentTopic, // message content topic + symKey: symKey, // symmetric key for encrypting messages +}); + +// Send the message using Light Push +await node.lightPush.send(encoder, { payload }); +``` + +To decrypt the messages you receive, create a symmetric message `decoder` and process the messages as usual: + +```js +import { createDecoder } from "@waku/message-encryption/symmetric"; + +// Create a symmetric message decoder +const decoder = createDecoder(contentTopic, symKey); + +// Receive messages from a Filter subscription +const subscription = await node.filter.createSubscription(); +await subscription.subscribe([decoder], callback); + +// Retrieve messages from Store peers +await node.store.queryWithOrderedCallback([decoder], callback); +``` + +## ECIES encryption + +ECIES encryption uses a public key for encryption and a private key for decryption. Use the `generatePrivateKey()` function to generate a random private key: + +```js +import { generatePrivateKey, getPublicKey } from "@waku/message-encryption"; + +// Generate a random private key, keep secure +const privateKey = generatePrivateKey(); + +// Generate a public key from the private key, provide to the sender +const publicKey = getPublicKey(privateKey); +``` + +To send encrypted messages, create an ECIES message `encoder` with the public key and send the message as usual: + +```js +import { createEncoder } from "@waku/message-encryption/ecies"; + +// Create an ECIES message encoder +const encoder = createEncoder({ + contentTopic: contentTopic, // message content topic + publicKey: publicKey, // ECIES public key for encrypting messages +}); + +// Send the message using Light Push +await node.lightPush.send(encoder, { payload }); +``` + +To decrypt the messages you receive, create an ECIES message `decoder` with the private key and process the messages as usual: + +```js +import { createDecoder } from "@waku/message-encryption/ecies"; + +// Create an ECIES message decoder +const decoder = createDecoder(contentTopic, privateKey); + +// Receive messages from a Filter subscription +const subscription = await node.filter.createSubscription(); +await subscription.subscribe([decoder], callback); + +// Retrieve messages from Store peers +await node.store.queryWithOrderedCallback([decoder], callback); +``` + +:::tip Congratulations! +You have successfully encrypted and decrypted your messages using `symmetric` and `ECIES` encryption methods. Have a look at the [flush-notes](https://github.com/waku-org/js-waku-examples/tree/master/examples/flush-notes) example for a working demo. +::: \ No newline at end of file diff --git a/docs/learn/waku-network.md b/docs/learn/waku-network.md index 44d120a4..31f50c09 100644 --- a/docs/learn/waku-network.md +++ b/docs/learn/waku-network.md @@ -3,10 +3,6 @@ title: The Waku Network hide_table_of_contents: true --- -:::info -The public Waku Network replaces the previous experimental shared routing layer based on a default pubsub topic (`/waku/2/default-waku/proto`). If your project currently uses this or any other shared pubsub topics, we encourage you to migrate to the public Waku Network with built-in DoS protection, with built-in DoS protection, scalability and reasonable bandwidth usage. -::: - The Waku Network is a shared p2p messaging network that is open-access, useful for generalized messaging, privacy-preserving, scalable and accessible even to resource-restricted devices. Some of the most prominent features include: 1. DoS/spam protection with privacy-preserving [Rate-Limiting Nullifiers](https://rfc.vac.dev/spec/64/#rln-rate-limiting). @@ -16,6 +12,10 @@ The Waku Network is a shared p2p messaging network that is open-access, useful f If you want to learn more about the Waku Network, the [WAKU2-NETWORK RFC](https://rfc.vac.dev/spec/64/) provides an in-depth look under the hood. +:::info +The public Waku Network replaces the previous experimental shared routing layer based on a default pubsub topic (`/waku/2/default-waku/proto`). If your project currently uses this or any other shared pubsub topics, we encourage you to migrate to the public Waku Network with built-in DoS protection, with built-in DoS protection, scalability, and reasonable bandwidth usage. +::: + ## Why join the Waku network? 1. Applications or projects can build decentralized communication components on this network, gaining from the fault-tolerance of shared infrastructure, the out-of-the-box censorship resistance of a p2p network and the privacy-preservation of Waku protocols. diff --git a/docusaurus.config.js b/docusaurus.config.js index 41963d88..c398ad72 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -150,6 +150,10 @@ const config = { href: "https://rfc.vac.dev/", label: "Vac RFCs", }, + { + href: "https://github.com/waku-org/awesome-waku/", + label: "Awesome Waku", + }, ], }, { diff --git a/sidebars.js b/sidebars.js index 13a1b654..655ad4f9 100644 --- a/sidebars.js +++ b/sidebars.js @@ -35,6 +35,7 @@ const sidebars = { items: [ "guides/js-waku/light-send-receive", "guides/js-waku/store-retrieve-messages", + "guides/js-waku/message-encryption", "guides/js-waku/use-waku-react", "guides/js-waku/use-waku-create-app", "guides/js-waku/configure-discovery", From 80f11b8ec066116c19a1c950daeb2f8abf8fd2a4 Mon Sep 17 00:00:00 2001 From: LordGhostX Date: Wed, 6 Dec 2023 12:44:14 +0100 Subject: [PATCH 02/12] add message signing guide --- docs/guides/js-waku/index.md | 2 +- docs/guides/js-waku/message-encryption.md | 45 +++++++++++++++++++---- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/docs/guides/js-waku/index.md b/docs/guides/js-waku/index.md index 066d6cce..606b337f 100644 --- a/docs/guides/js-waku/index.md +++ b/docs/guides/js-waku/index.md @@ -85,7 +85,7 @@ Have a look at the quick start guide and comprehensive tutorials to learn how to | - | - | | [Send and Receive Messages Using Light Push and Filter](/guides/js-waku/light-send-receive) | Learn how to send and receive messages on light nodes using the [Light Push](/learn/concepts/protocols#light-push) and [Filter](/learn/concepts/protocols#filter) protocols | | [Retrieve Messages Using Store Protocol](/guides/js-waku/store-retrieve-messages) | Learn how to retrieve and filter historical messages on light nodes using the [Store protocol](/learn/concepts/protocols#store) | -| [Encrypt and Decrypt Your Waku Messages](/guides/js-waku/message-encryption) | Learn how to use the [@waku/message-encryption](https://www.npmjs.com/package/@waku/message-encryption) package to encrypt and decrypt your messages | +| [Encrypt, Decrypt, and Sign Your Messages](/guides/js-waku/message-encryption) | Learn how to use the [@waku/message-encryption](https://www.npmjs.com/package/@waku/message-encryption) package to encrypt, decrypt, and sign your messages | | [Build React DApps Using @waku/react](/guides/js-waku/use-waku-react) | Learn how to use the [@waku/react](https://www.npmjs.com/package/@waku/react) package seamlessly integrate `@waku/sdk` into a React application | | [Scaffold DApps Using @waku/create-app](/guides/js-waku/use-waku-create-app) | Learn how to use the [@waku/create-app](https://www.npmjs.com/package/@waku/create-app) package to bootstrap your next `@waku/sdk` project from various example templates | | [Bootstrap Nodes and Discover Peers](/guides/js-waku/configure-discovery) | Learn how to bootstrap your node using [Static Peers](/learn/concepts/static-peers) and discover peers using [DNS Discovery](/learn/concepts/dns-discovery) | diff --git a/docs/guides/js-waku/message-encryption.md b/docs/guides/js-waku/message-encryption.md index 9b1c21eb..fa859950 100644 --- a/docs/guides/js-waku/message-encryption.md +++ b/docs/guides/js-waku/message-encryption.md @@ -1,9 +1,9 @@ --- -title: Encrypt and Decrypt Your Waku Messages +title: Encrypt, Decrypt, and Sign Your Messages hide_table_of_contents: true --- -This guide provides detailed steps to use the [@waku/message-encryption](https://www.npmjs.com/package/@waku/message-encryption) package to encrypt and decrypt your messages using [Waku message payload encryption](/learn/glossary#waku-message-payload-encryption) methods. +This guide provides detailed steps to use the [@waku/message-encryption](https://www.npmjs.com/package/@waku/message-encryption) package to encrypt, decrypt, and sign your messages using [Waku message payload encryption](/learn/glossary#waku-message-payload-encryption) methods. :::info Waku lacks protocol-level message encryption because it does not know the communication parties. This design choice enhances Waku's encryption flexibility, encouraging developers to freely use custom protocols or [Waku message payload encryption](/learn/glossary#waku-message-payload-encryption) methods. @@ -37,7 +37,7 @@ yarn add @waku/message-encryption ## Symmetric encryption -Symmetric encryption uses a single, shared key for message encryption and decryption. Use the `generateSymmetricKey()` function to generate a random symmetric key: +`Symmetric` encryption uses a single, shared key for message encryption and decryption. Use the `generateSymmetricKey()` function to generate a random symmetric key: ```js import { generateSymmetricKey } from "@waku/message-encryption"; @@ -46,7 +46,7 @@ import { generateSymmetricKey } from "@waku/message-encryption"; const symKey = generateSymmetricKey(); ``` -To send encrypted messages, create a symmetric message `encoder` and send the message as usual: +To send encrypted messages, create a `Symmetric` message `encoder` and send the message as usual: ```js import { createEncoder } from "@waku/message-encryption/symmetric"; @@ -79,7 +79,7 @@ await node.store.queryWithOrderedCallback([decoder], callback); ## ECIES encryption -ECIES encryption uses a public key for encryption and a private key for decryption. Use the `generatePrivateKey()` function to generate a random private key: +`ECIES` encryption uses a public key for encryption and a private key for decryption. Use the `generatePrivateKey()` function to generate a random private key: ```js import { generatePrivateKey, getPublicKey } from "@waku/message-encryption"; @@ -91,7 +91,7 @@ const privateKey = generatePrivateKey(); const publicKey = getPublicKey(privateKey); ``` -To send encrypted messages, create an ECIES message `encoder` with the public key and send the message as usual: +To send encrypted messages, create an `ECIES` message `encoder` with the public key and send the message as usual: ```js import { createEncoder } from "@waku/message-encryption/ecies"; @@ -106,7 +106,7 @@ const encoder = createEncoder({ await node.lightPush.send(encoder, { payload }); ``` -To decrypt the messages you receive, create an ECIES message `decoder` with the private key and process the messages as usual: +To decrypt the messages you receive, create an `ECIES` message `decoder` with the private key and process the messages as usual: ```js import { createDecoder } from "@waku/message-encryption/ecies"; @@ -122,6 +122,35 @@ await subscription.subscribe([decoder], callback); await node.store.queryWithOrderedCallback([decoder], callback); ``` +## Signing encrypted messages + +Message signing helps in proving the authenticity of received messages. By attaching a signature to a message, you can verify its origin and integrity with absolute certainty. + +The `sigPrivKey` option allows the `Symmetric` and `ECIES` message `encoders` to sign the message before encryption using an `ECDSA` private key: + +```js +import { generatePrivateKey } from "@waku/message-encryption"; +import { createEncoder as createSymmetricEncoder } from "@waku/message-encryption/symmetric"; +import { createEncoder as createECIESEncoder } from "@waku/message-encryption/ecies"; + +// Generate a random private key for signing messages +const sigPrivKey = generatePrivateKey(); + +// Create a symmetric encoder that signs messages +const symmetricEncoder = createSymmetricEncoder({ + contentTopic: contentTopic, // message content topic + symKey: symKey, // symmetric key for encrypting messages + sigPrivKey: sigPrivKey, // private key for signing messages before encryption +}); + +// Create an ECIES encoder that signs messages +const ECIESEncoder = createECIESEncoder({ + contentTopic: contentTopic, // message content topic + publicKey: publicKey, // ECIES public key for encrypting messages + sigPrivKey: sigPrivKey, // private key for signing messages before encryption +}); +``` + :::tip Congratulations! -You have successfully encrypted and decrypted your messages using `symmetric` and `ECIES` encryption methods. Have a look at the [flush-notes](https://github.com/waku-org/js-waku-examples/tree/master/examples/flush-notes) example for a working demo. +You have successfully encrypted, decrypted, and signed your messages using `symmetric` and `ECIES` encryption methods. Have a look at the [flush-notes](https://github.com/waku-org/js-waku-examples/tree/master/examples/flush-notes) example for a working demo. ::: \ No newline at end of file From 34b7510b2de28a62506592c344abd6e99436f1ac Mon Sep 17 00:00:00 2001 From: LordGhostX Date: Wed, 6 Dec 2023 14:22:06 +0100 Subject: [PATCH 03/12] add signature validation guide --- docs/guides/js-waku/message-encryption.md | 38 +++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/guides/js-waku/message-encryption.md b/docs/guides/js-waku/message-encryption.md index fa859950..8752bc05 100644 --- a/docs/guides/js-waku/message-encryption.md +++ b/docs/guides/js-waku/message-encryption.md @@ -149,6 +149,44 @@ const ECIESEncoder = createECIESEncoder({ publicKey: publicKey, // ECIES public key for encrypting messages sigPrivKey: sigPrivKey, // private key for signing messages before encryption }); + +// Send and receive your messages as usual with Light Push and Filter +await node.lightPush.send(symmetricEncoder, { payload }); +await subscription.subscribe([symmetricEncoder], callback); + +await node.lightPush.send(ECIESEncoder, { payload }); +await subscription.subscribe([ECIESEncoder], callback); +``` + +You can extract the `signature` and its public key (`signaturePublicKey`) from the [DecodedMessage](https://js.waku.org/classes/_waku_message_encryption.DecodedMessage.html) and compare it with the expected public key to verify the message: + +```js +// Generate a random private key for signing messages +const sigPrivKey = generatePrivateKey(); + +// Generate a public key from the private key for verifying signatures +const sigPubKey = getPublicKey(sigPrivKey); + +// Create an encoder that signs messages +const encoder = createEncoder({ + contentTopic: contentTopic, + symKey: symKey, + sigPrivKey: sigPrivKey, +}); + +// Modify the callback function to verify message signature +const callback = (wakuMessage) => { + // Extract the message signature and public key of the signature + const signature = wakuMessage.signature; + const signaturePublicKey = wakuMessage.signaturePublicKey; + + // Compare the public key of the message signature with the sender's own + if (JSON.stringify(signaturePublicKey) === JSON.stringify(sigPubKey)) { + console.log("This message was correctly signed"); + } else { + console.log("This message has an incorrect signature"); + } +}; ``` :::tip Congratulations! From 481dee859570c9b721933ed1d1b9945d7c7b9673 Mon Sep 17 00:00:00 2001 From: LordGhostX Date: Wed, 6 Dec 2023 15:21:57 +0100 Subject: [PATCH 04/12] add key restoration guide --- docs/guides/js-waku/message-encryption.md | 44 +++++++++++++++++------ 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/docs/guides/js-waku/message-encryption.md b/docs/guides/js-waku/message-encryption.md index 8752bc05..f08221d6 100644 --- a/docs/guides/js-waku/message-encryption.md +++ b/docs/guides/js-waku/message-encryption.md @@ -22,14 +22,14 @@ import TabItem from '@theme/TabItem'; ```shell -npm install @waku/message-encryption +npm install @waku/message-encryption @waku/utils ``` ```shell -yarn add @waku/message-encryption +yarn add @waku/message-encryption @waku/utils ``` @@ -138,24 +138,24 @@ const sigPrivKey = generatePrivateKey(); // Create a symmetric encoder that signs messages const symmetricEncoder = createSymmetricEncoder({ - contentTopic: contentTopic, // message content topic - symKey: symKey, // symmetric key for encrypting messages + contentTopic: contentTopic, // message content topic + symKey: symKey, // symmetric key for encrypting messages sigPrivKey: sigPrivKey, // private key for signing messages before encryption }); // Create an ECIES encoder that signs messages const ECIESEncoder = createECIESEncoder({ - contentTopic: contentTopic, // message content topic - publicKey: publicKey, // ECIES public key for encrypting messages + contentTopic: contentTopic, // message content topic + publicKey: publicKey, // ECIES public key for encrypting messages sigPrivKey: sigPrivKey, // private key for signing messages before encryption }); // Send and receive your messages as usual with Light Push and Filter -await node.lightPush.send(symmetricEncoder, { payload }); await subscription.subscribe([symmetricEncoder], callback); +await node.lightPush.send(symmetricEncoder, { payload }); -await node.lightPush.send(ECIESEncoder, { payload }); await subscription.subscribe([ECIESEncoder], callback); +await node.lightPush.send(ECIESEncoder, { payload }); ``` You can extract the `signature` and its public key (`signaturePublicKey`) from the [DecodedMessage](https://js.waku.org/classes/_waku_message_encryption.DecodedMessage.html) and compare it with the expected public key to verify the message: @@ -169,8 +169,8 @@ const sigPubKey = getPublicKey(sigPrivKey); // Create an encoder that signs messages const encoder = createEncoder({ - contentTopic: contentTopic, - symKey: symKey, + contentTopic: contentTopic, + symKey: symKey, sigPrivKey: sigPrivKey, }); @@ -189,6 +189,30 @@ const callback = (wakuMessage) => { }; ``` +## Restoring encryption keys + +We used randomly generated keys for encryption and message signing in the provided examples, but real-world applications require consistent keys among clients. You can use the [@waku/utils](https://www.npmjs.com/package/@waku/utils) package to convert keys into a hexadecimal format for uniformity: + +```js +import { bytesToHex, hexToBytes } from "@waku/utils/bytes"; +import { generateSymmetricKey, generatePrivateKey } from "@waku/message-encryption"; + +// Generate random symmetric and private keys +const symKey = generateSymmetricKey(); +const privateKey = generatePrivateKey(); +console.log(symKey, privateKey); + +// Convert the keys to hexadecimal format +const symKeyHex = bytesToHex(symKey); +const privateKeyHex = bytesToHex(privateKey); +console.log(symKeyHex, privateKeyHex); + +// Restore the keys from hexadecimal format +const restoredSymKey = hexToBytes(symKeyHex); +const restoredPrivateKey = hexToBytes(privateKeyHex); +console.log(restoredSymKey, restoredPrivateKey); +``` + :::tip Congratulations! You have successfully encrypted, decrypted, and signed your messages using `symmetric` and `ECIES` encryption methods. Have a look at the [flush-notes](https://github.com/waku-org/js-waku-examples/tree/master/examples/flush-notes) example for a working demo. ::: \ No newline at end of file From 69a15a1c6b5e9f2229721d94b9aa10d4b4f3a05f Mon Sep 17 00:00:00 2001 From: LordGhostX Date: Thu, 7 Dec 2023 13:08:42 +0100 Subject: [PATCH 05/12] add initial feedback --- docs/guides/js-waku/message-encryption.md | 23 ++++++++++++++++++----- docs/learn/glossary.md | 4 ++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/docs/guides/js-waku/message-encryption.md b/docs/guides/js-waku/message-encryption.md index f08221d6..fafdd4b2 100644 --- a/docs/guides/js-waku/message-encryption.md +++ b/docs/guides/js-waku/message-encryption.md @@ -6,7 +6,7 @@ hide_table_of_contents: true This guide provides detailed steps to use the [@waku/message-encryption](https://www.npmjs.com/package/@waku/message-encryption) package to encrypt, decrypt, and sign your messages using [Waku message payload encryption](/learn/glossary#waku-message-payload-encryption) methods. :::info -Waku lacks protocol-level message encryption because it does not know the communication parties. This design choice enhances Waku's encryption flexibility, encouraging developers to freely use custom protocols or [Waku message payload encryption](/learn/glossary#waku-message-payload-encryption) methods. +Waku uses libp2p noise encryption for node-to-node connections. However, no default encryption method is applied to the data sent over the network. This design choice enhances Waku's encryption flexibility, encouraging developers to freely use custom protocols or [Waku message payload encryption](/learn/glossary#waku-message-payload-encryption) methods. ::: ## Installation @@ -77,14 +77,18 @@ await subscription.subscribe([decoder], callback); await node.store.queryWithOrderedCallback([decoder], callback); ``` +:::tip +The symmetric key exchange between users can happen through an [out-of-band method](/learn/glossary#out-of-band). For example, where the key is embedded within the URL shared by a user to access a specific resource. +::: + ## ECIES encryption -`ECIES` encryption uses a public key for encryption and a private key for decryption. Use the `generatePrivateKey()` function to generate a random private key: +`ECIES` encryption uses a public key for encryption and a private key for decryption. Use the `generatePrivateKey()` function to generate a random `ECDSA` private key: ```js import { generatePrivateKey, getPublicKey } from "@waku/message-encryption"; -// Generate a random private key, keep secure +// Generate a random ECDSA private key, keep secure const privateKey = generatePrivateKey(); // Generate a public key from the private key, provide to the sender @@ -122,10 +126,18 @@ await subscription.subscribe([decoder], callback); await node.store.queryWithOrderedCallback([decoder], callback); ``` +:::tip +Users can share their public key through broadcasting or [out-of-band methods](/learn/glossary#out-of-band), such as embedding it in a URL or sending an unencrypted message on another content topic for others to retrieve. +::: + ## Signing encrypted messages Message signing helps in proving the authenticity of received messages. By attaching a signature to a message, you can verify its origin and integrity with absolute certainty. +:::info +Signing messages is only possible when encrypted, but if your app does not require encryption, you can generate a symmetric key through hardcoded or deterministic methods using information available to all users. +::: + The `sigPrivKey` option allows the `Symmetric` and `ECIES` message `encoders` to sign the message before encryption using an `ECDSA` private key: ```js @@ -133,7 +145,8 @@ import { generatePrivateKey } from "@waku/message-encryption"; import { createEncoder as createSymmetricEncoder } from "@waku/message-encryption/symmetric"; import { createEncoder as createECIESEncoder } from "@waku/message-encryption/ecies"; -// Generate a random private key for signing messages +// Generate a random ECDSA private key for signing messages +// ECIES encryption and message signing both use ECDSA keys const sigPrivKey = generatePrivateKey(); // Create a symmetric encoder that signs messages @@ -158,7 +171,7 @@ await subscription.subscribe([ECIESEncoder], callback); await node.lightPush.send(ECIESEncoder, { payload }); ``` -You can extract the `signature` and its public key (`signaturePublicKey`) from the [DecodedMessage](https://js.waku.org/classes/_waku_message_encryption.DecodedMessage.html) and compare it with the expected public key to verify the message: +You can extract the `signature` and its public key (`signaturePublicKey`) from the [DecodedMessage](https://js.waku.org/classes/_waku_message_encryption.DecodedMessage.html) and compare it with the expected public key to verify the message origin: ```js // Generate a random private key for signing messages diff --git a/docs/learn/glossary.md b/docs/learn/glossary.md index fc8b9942..ded097b9 100644 --- a/docs/learn/glossary.md +++ b/docs/learn/glossary.md @@ -63,6 +63,10 @@ A node is a device or client that implements Waku [protocols](#protocol) and lev A node key is a [Secp256k1](https://en.bitcoin.it/wiki/Secp256k1) (64-char hex string) private key for generating the [PeerID](#peer-id), [listening](#transport) addresses, and [discovery](#peer-discovery) addresses of a Waku node. +### Out-of-band + +Out-of-band refers to exchanging information through a separate, secure channel distinct from the main communication method to enhance security. + ### Payload The payload field in a [Waku Message](#waku-message) contains the application data, serving as the business logic message transmitted between clients over Waku. Applications can encrypt the payload or employ encryption methods specified in [Waku Message Payload Encryption](#waku-message-payload-encryption). From 1b50902196bd9263338efd239124d16bb3ab628e Mon Sep 17 00:00:00 2001 From: LordGhostX Date: Thu, 7 Dec 2023 13:42:25 +0100 Subject: [PATCH 06/12] use uint8arrays/equals for signature verification --- docs/guides/js-waku/message-encryption.md | 10 ++++++---- docs/guides/js-waku/use-waku-react.md | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/guides/js-waku/message-encryption.md b/docs/guides/js-waku/message-encryption.md index fafdd4b2..1d8ef916 100644 --- a/docs/guides/js-waku/message-encryption.md +++ b/docs/guides/js-waku/message-encryption.md @@ -11,7 +11,7 @@ Waku uses libp2p noise encryption for node-to-node connections. However, no defa ## Installation -Install the `@waku/message-encryption` package using your preferred package manager: +Install the required packages for integrating `@waku/message-encryption` using your preferred package manager: ```mdx-code-block import Tabs from '@theme/Tabs'; @@ -22,14 +22,14 @@ import TabItem from '@theme/TabItem'; ```shell -npm install @waku/message-encryption @waku/utils +npm install @waku/message-encryption @waku/utils uint8arrays ``` ```shell -yarn add @waku/message-encryption @waku/utils +yarn add @waku/message-encryption @waku/utils uint8arrays ``` @@ -174,6 +174,8 @@ await node.lightPush.send(ECIESEncoder, { payload }); You can extract the `signature` and its public key (`signaturePublicKey`) from the [DecodedMessage](https://js.waku.org/classes/_waku_message_encryption.DecodedMessage.html) and compare it with the expected public key to verify the message origin: ```js +import { equals } from "uint8arrays/equals"; + // Generate a random private key for signing messages const sigPrivKey = generatePrivateKey(); @@ -194,7 +196,7 @@ const callback = (wakuMessage) => { const signaturePublicKey = wakuMessage.signaturePublicKey; // Compare the public key of the message signature with the sender's own - if (JSON.stringify(signaturePublicKey) === JSON.stringify(sigPubKey)) { + if (equals(signaturePublicKey, sigPubKey)) { console.log("This message was correctly signed"); } else { console.log("This message has an incorrect signature"); diff --git a/docs/guides/js-waku/use-waku-react.md b/docs/guides/js-waku/use-waku-react.md index b8f7ff40..e4230b0d 100644 --- a/docs/guides/js-waku/use-waku-react.md +++ b/docs/guides/js-waku/use-waku-react.md @@ -31,7 +31,7 @@ yarn create vite [PROJECT DIRECTORY] --template react -Next, install the required libraries for integrating `@waku/sdk` using your preferred package manager: +Next, install the required packages for integrating `@waku/sdk` using your preferred package manager: From 0f4769fe379b14ba4a13c2092d646f8866bfef3d Mon Sep 17 00:00:00 2001 From: LordGhostX Date: Fri, 8 Dec 2023 13:42:01 +0100 Subject: [PATCH 07/12] add Alice/Bob references for signing --- docs/guides/js-waku/message-encryption.md | 37 +++++++++++++---------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/docs/guides/js-waku/message-encryption.md b/docs/guides/js-waku/message-encryption.md index 1d8ef916..e269ac56 100644 --- a/docs/guides/js-waku/message-encryption.md +++ b/docs/guides/js-waku/message-encryption.md @@ -135,32 +135,34 @@ Users can share their public key through broadcasting or [out-of-band methods](/ Message signing helps in proving the authenticity of received messages. By attaching a signature to a message, you can verify its origin and integrity with absolute certainty. :::info -Signing messages is only possible when encrypted, but if your app does not require encryption, you can generate a symmetric key through hardcoded or deterministic methods using information available to all users. +Signing messages is only possible when encrypted, but if your application does not require encryption, you can generate a symmetric key through hardcoded or deterministic methods using information available to all users. ::: The `sigPrivKey` option allows the `Symmetric` and `ECIES` message `encoders` to sign the message before encryption using an `ECDSA` private key: -```js -import { generatePrivateKey } from "@waku/message-encryption"; +```js title="Alice (Sender) Client" +import { generatePrivateKey, getPublicKey } from "@waku/message-encryption"; import { createEncoder as createSymmetricEncoder } from "@waku/message-encryption/symmetric"; import { createEncoder as createECIESEncoder } from "@waku/message-encryption/ecies"; // Generate a random ECDSA private key for signing messages // ECIES encryption and message signing both use ECDSA keys -const sigPrivKey = generatePrivateKey(); +// For this example, we'll call the sender of the message Alice +const aliceSigPrivKey = generatePrivateKey(); +const aliceSigPubKey = getPublicKey(aliceSigPrivKey); // Create a symmetric encoder that signs messages const symmetricEncoder = createSymmetricEncoder({ contentTopic: contentTopic, // message content topic symKey: symKey, // symmetric key for encrypting messages - sigPrivKey: sigPrivKey, // private key for signing messages before encryption + sigPrivKey: aliceSigPrivKey, // private key for signing messages before encryption }); // Create an ECIES encoder that signs messages const ECIESEncoder = createECIESEncoder({ contentTopic: contentTopic, // message content topic publicKey: publicKey, // ECIES public key for encrypting messages - sigPrivKey: sigPrivKey, // private key for signing messages before encryption + sigPrivKey: aliceSigPrivKey, // private key for signing messages before encryption }); // Send and receive your messages as usual with Light Push and Filter @@ -173,20 +175,20 @@ await node.lightPush.send(ECIESEncoder, { payload }); You can extract the `signature` and its public key (`signaturePublicKey`) from the [DecodedMessage](https://js.waku.org/classes/_waku_message_encryption.DecodedMessage.html) and compare it with the expected public key to verify the message origin: -```js +```js title="Bob (Receiver) Client" +import { generatePrivateKey } from "@waku/message-encryption"; +import { createEncoder } from "@waku/message-encryption/symmetric"; import { equals } from "uint8arrays/equals"; // Generate a random private key for signing messages -const sigPrivKey = generatePrivateKey(); - -// Generate a public key from the private key for verifying signatures -const sigPubKey = getPublicKey(sigPrivKey); +// For this example, we'll call the receiver of the message Bob +const bobSigPrivKey = generatePrivateKey(); // Create an encoder that signs messages const encoder = createEncoder({ contentTopic: contentTopic, symKey: symKey, - sigPrivKey: sigPrivKey, + sigPrivKey: bobSigPrivKey, }); // Modify the callback function to verify message signature @@ -195,13 +197,16 @@ const callback = (wakuMessage) => { const signature = wakuMessage.signature; const signaturePublicKey = wakuMessage.signaturePublicKey; - // Compare the public key of the message signature with the sender's own - if (equals(signaturePublicKey, sigPubKey)) { - console.log("This message was correctly signed"); + // Compare the public key of the message signature with Alice's own + // Alice's public key can be gotten from broadcasting or out-of-band methods + if (equals(signaturePublicKey, aliceSigPubKey)) { + console.log("This message was signed by Alice"); } else { - console.log("This message has an incorrect signature"); + console.log("This message was NOT signed by Alice"); } }; + +await subscription.subscribe([encoder], callback); ``` ## Restoring encryption keys From bc4828004f49b0fedd59c6a796b11a5c2a23d9a0 Mon Sep 17 00:00:00 2001 From: LordGhostX Date: Fri, 8 Dec 2023 14:28:05 +0100 Subject: [PATCH 08/12] add key_pair_handling demo --- docs/guides/js-waku/message-encryption.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/guides/js-waku/message-encryption.md b/docs/guides/js-waku/message-encryption.md index e269ac56..6c45cf8b 100644 --- a/docs/guides/js-waku/message-encryption.md +++ b/docs/guides/js-waku/message-encryption.md @@ -211,28 +211,26 @@ await subscription.subscribe([encoder], callback); ## Restoring encryption keys -We used randomly generated keys for encryption and message signing in the provided examples, but real-world applications require consistent keys among clients. You can use the [@waku/utils](https://www.npmjs.com/package/@waku/utils) package to convert keys into a hexadecimal format for uniformity: +We used randomly generated keys for encryption and message signing in the provided examples, but real-world applications require consistent keys among clients. Have a look at the [Key Pair Handling](https://github.com/waku-org/js-waku-examples/tree/master/examples/eth-pm/src/key_pair_handling) example, which demonstrates the secure storage and retrieval of key information from local storage using [Subtle Crypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto). + +You can also use the [@waku/utils](https://www.npmjs.com/package/@waku/utils) package to convert keys into hexadecimal format: ```js import { bytesToHex, hexToBytes } from "@waku/utils/bytes"; -import { generateSymmetricKey, generatePrivateKey } from "@waku/message-encryption"; // Generate random symmetric and private keys const symKey = generateSymmetricKey(); const privateKey = generatePrivateKey(); -console.log(symKey, privateKey); // Convert the keys to hexadecimal format const symKeyHex = bytesToHex(symKey); const privateKeyHex = bytesToHex(privateKey); -console.log(symKeyHex, privateKeyHex); // Restore the keys from hexadecimal format const restoredSymKey = hexToBytes(symKeyHex); const restoredPrivateKey = hexToBytes(privateKeyHex); -console.log(restoredSymKey, restoredPrivateKey); ``` :::tip Congratulations! -You have successfully encrypted, decrypted, and signed your messages using `symmetric` and `ECIES` encryption methods. Have a look at the [flush-notes](https://github.com/waku-org/js-waku-examples/tree/master/examples/flush-notes) example for a working demo. +You have successfully encrypted, decrypted, and signed your messages using `Symmetric` and `ECIES` encryption methods. Have a look at the [flush-notes](https://github.com/waku-org/js-waku-examples/tree/master/examples/flush-notes) and [eth-pm](https://github.com/waku-org/js-waku-examples/tree/master/examples/eth-pm) examples for working demos. ::: \ No newline at end of file From 37f900b4ce5cf353f96ed6c5f144ebc09d0f5175 Mon Sep 17 00:00:00 2001 From: LordGhostX Date: Fri, 8 Dec 2023 14:35:38 +0100 Subject: [PATCH 09/12] restore -> store renaming --- docs/guides/js-waku/message-encryption.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/guides/js-waku/message-encryption.md b/docs/guides/js-waku/message-encryption.md index 6c45cf8b..309835b0 100644 --- a/docs/guides/js-waku/message-encryption.md +++ b/docs/guides/js-waku/message-encryption.md @@ -48,7 +48,7 @@ const symKey = generateSymmetricKey(); To send encrypted messages, create a `Symmetric` message `encoder` and send the message as usual: -```js +```js title="Sender client" import { createEncoder } from "@waku/message-encryption/symmetric"; // Create a symmetric message encoder @@ -63,7 +63,7 @@ await node.lightPush.send(encoder, { payload }); To decrypt the messages you receive, create a symmetric message `decoder` and process the messages as usual: -```js +```js title="Receiver client" import { createDecoder } from "@waku/message-encryption/symmetric"; // Create a symmetric message decoder @@ -97,7 +97,7 @@ const publicKey = getPublicKey(privateKey); To send encrypted messages, create an `ECIES` message `encoder` with the public key and send the message as usual: -```js +```js title="Sender client" import { createEncoder } from "@waku/message-encryption/ecies"; // Create an ECIES message encoder @@ -112,7 +112,7 @@ await node.lightPush.send(encoder, { payload }); To decrypt the messages you receive, create an `ECIES` message `decoder` with the private key and process the messages as usual: -```js +```js title="Receiver client" import { createDecoder } from "@waku/message-encryption/ecies"; // Create an ECIES message decoder @@ -140,7 +140,7 @@ Signing messages is only possible when encrypted, but if your application does n The `sigPrivKey` option allows the `Symmetric` and `ECIES` message `encoders` to sign the message before encryption using an `ECDSA` private key: -```js title="Alice (Sender) Client" +```js title="Alice (sender) client" import { generatePrivateKey, getPublicKey } from "@waku/message-encryption"; import { createEncoder as createSymmetricEncoder } from "@waku/message-encryption/symmetric"; import { createEncoder as createECIESEncoder } from "@waku/message-encryption/ecies"; @@ -175,7 +175,7 @@ await node.lightPush.send(ECIESEncoder, { payload }); You can extract the `signature` and its public key (`signaturePublicKey`) from the [DecodedMessage](https://js.waku.org/classes/_waku_message_encryption.DecodedMessage.html) and compare it with the expected public key to verify the message origin: -```js title="Bob (Receiver) Client" +```js title="Bob (receiver) client" import { generatePrivateKey } from "@waku/message-encryption"; import { createEncoder } from "@waku/message-encryption/symmetric"; import { equals } from "uint8arrays/equals"; @@ -209,11 +209,11 @@ const callback = (wakuMessage) => { await subscription.subscribe([encoder], callback); ``` -## Restoring encryption keys +## Storing encryption keys We used randomly generated keys for encryption and message signing in the provided examples, but real-world applications require consistent keys among clients. Have a look at the [Key Pair Handling](https://github.com/waku-org/js-waku-examples/tree/master/examples/eth-pm/src/key_pair_handling) example, which demonstrates the secure storage and retrieval of key information from local storage using [Subtle Crypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto). -You can also use the [@waku/utils](https://www.npmjs.com/package/@waku/utils) package to convert keys into hexadecimal format: +You can also use the [@waku/utils](https://www.npmjs.com/package/@waku/utils) package to store keys in hexadecimal format: ```js import { bytesToHex, hexToBytes } from "@waku/utils/bytes"; @@ -222,7 +222,7 @@ import { bytesToHex, hexToBytes } from "@waku/utils/bytes"; const symKey = generateSymmetricKey(); const privateKey = generatePrivateKey(); -// Convert the keys to hexadecimal format +// Store the keys in hexadecimal format const symKeyHex = bytesToHex(symKey); const privateKeyHex = bytesToHex(privateKey); From 854a3df0900d9a2cc6badf9e462a70501e0c9a8d Mon Sep 17 00:00:00 2001 From: LordGhostX Date: Tue, 12 Dec 2023 16:53:38 +0100 Subject: [PATCH 10/12] add verifySignature function --- docs/guides/js-waku/message-encryption.md | 42 +++++++++++------------ 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/docs/guides/js-waku/message-encryption.md b/docs/guides/js-waku/message-encryption.md index 309835b0..4daf359f 100644 --- a/docs/guides/js-waku/message-encryption.md +++ b/docs/guides/js-waku/message-encryption.md @@ -22,14 +22,14 @@ import TabItem from '@theme/TabItem'; ```shell -npm install @waku/message-encryption @waku/utils uint8arrays +npm install @waku/message-encryption @waku/utils ``` ```shell -yarn add @waku/message-encryption @waku/utils uint8arrays +yarn add @waku/message-encryption @waku/utils ``` @@ -43,7 +43,7 @@ yarn add @waku/message-encryption @waku/utils uint8arrays import { generateSymmetricKey } from "@waku/message-encryption"; // Generate a random symmetric key -const symKey = generateSymmetricKey(); +const symmetricKey = generateSymmetricKey(); ``` To send encrypted messages, create a `Symmetric` message `encoder` and send the message as usual: @@ -54,7 +54,7 @@ import { createEncoder } from "@waku/message-encryption/symmetric"; // Create a symmetric message encoder const encoder = createEncoder({ contentTopic: contentTopic, // message content topic - symKey: symKey, // symmetric key for encrypting messages + symKey: symmetricKey, // symmetric key for encrypting messages }); // Send the message using Light Push @@ -67,10 +67,9 @@ To decrypt the messages you receive, create a symmetric message `decoder` and pr import { createDecoder } from "@waku/message-encryption/symmetric"; // Create a symmetric message decoder -const decoder = createDecoder(contentTopic, symKey); +const decoder = createDecoder(contentTopic, symmetricKey); // Receive messages from a Filter subscription -const subscription = await node.filter.createSubscription(); await subscription.subscribe([decoder], callback); // Retrieve messages from Store peers @@ -119,7 +118,6 @@ import { createDecoder } from "@waku/message-encryption/ecies"; const decoder = createDecoder(contentTopic, privateKey); // Receive messages from a Filter subscription -const subscription = await node.filter.createSubscription(); await subscription.subscribe([decoder], callback); // Retrieve messages from Store peers @@ -148,21 +146,21 @@ import { createEncoder as createECIESEncoder } from "@waku/message-encryption/ec // Generate a random ECDSA private key for signing messages // ECIES encryption and message signing both use ECDSA keys // For this example, we'll call the sender of the message Alice -const aliceSigPrivKey = generatePrivateKey(); -const aliceSigPubKey = getPublicKey(aliceSigPrivKey); +const alicePrivateKey = generatePrivateKey(); +const alicePublicKey = getPublicKey(alicePrivateKey); // Create a symmetric encoder that signs messages const symmetricEncoder = createSymmetricEncoder({ contentTopic: contentTopic, // message content topic - symKey: symKey, // symmetric key for encrypting messages - sigPrivKey: aliceSigPrivKey, // private key for signing messages before encryption + symKey: symmetricKey, // symmetric key for encrypting messages + sigPrivKey: alicePrivateKey, // private key for signing messages before encryption }); // Create an ECIES encoder that signs messages const ECIESEncoder = createECIESEncoder({ contentTopic: contentTopic, // message content topic publicKey: publicKey, // ECIES public key for encrypting messages - sigPrivKey: aliceSigPrivKey, // private key for signing messages before encryption + sigPrivKey: alicePrivateKey, // private key for signing messages before encryption }); // Send and receive your messages as usual with Light Push and Filter @@ -173,33 +171,33 @@ await subscription.subscribe([ECIESEncoder], callback); await node.lightPush.send(ECIESEncoder, { payload }); ``` -You can extract the `signature` and its public key (`signaturePublicKey`) from the [DecodedMessage](https://js.waku.org/classes/_waku_message_encryption.DecodedMessage.html) and compare it with the expected public key to verify the message origin: +You can extract the `signature` and its public key (`signaturePublicKey`) from the [DecodedMessage](https://js.waku.org/classes/_waku_message_encryption.DecodedMessage.html) and compare it with the expected public key or use the `verifySignature()` function to verify the message origin: ```js title="Bob (receiver) client" import { generatePrivateKey } from "@waku/message-encryption"; import { createEncoder } from "@waku/message-encryption/symmetric"; -import { equals } from "uint8arrays/equals"; // Generate a random private key for signing messages // For this example, we'll call the receiver of the message Bob -const bobSigPrivKey = generatePrivateKey(); +const bobPrivateKey = generatePrivateKey(); // Create an encoder that signs messages const encoder = createEncoder({ contentTopic: contentTopic, - symKey: symKey, - sigPrivKey: bobSigPrivKey, + symKey: symmetricKey, + sigPrivKey: bobPrivateKey, }); // Modify the callback function to verify message signature const callback = (wakuMessage) => { // Extract the message signature and public key of the signature + // You can compare the signaturePublicKey with Alice public key const signature = wakuMessage.signature; const signaturePublicKey = wakuMessage.signaturePublicKey; - // Compare the public key of the message signature with Alice's own + // Verify the message was actually signed and sent by Alice // Alice's public key can be gotten from broadcasting or out-of-band methods - if (equals(signaturePublicKey, aliceSigPubKey)) { + if (wakuMessage.verifySignature(alicePublicKey)) { console.log("This message was signed by Alice"); } else { console.log("This message was NOT signed by Alice"); @@ -219,15 +217,15 @@ You can also use the [@waku/utils](https://www.npmjs.com/package/@waku/utils) pa import { bytesToHex, hexToBytes } from "@waku/utils/bytes"; // Generate random symmetric and private keys -const symKey = generateSymmetricKey(); +const symmetricKey = generateSymmetricKey(); const privateKey = generatePrivateKey(); // Store the keys in hexadecimal format -const symKeyHex = bytesToHex(symKey); +const symmetricKeyHex = bytesToHex(symmetricKey); const privateKeyHex = bytesToHex(privateKey); // Restore the keys from hexadecimal format -const restoredSymKey = hexToBytes(symKeyHex); +const restoredSymmetricKey = hexToBytes(symmetricKeyHex); const restoredPrivateKey = hexToBytes(privateKeyHex); ``` From 8748b59e122128c5030a779864aafef1568f4c63 Mon Sep 17 00:00:00 2001 From: LordGhostX Date: Tue, 9 Jan 2024 16:55:03 +0100 Subject: [PATCH 11/12] add vpavlin feedback --- docs/guides/js-waku/message-encryption.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/js-waku/message-encryption.md b/docs/guides/js-waku/message-encryption.md index 4daf359f..83abc3d0 100644 --- a/docs/guides/js-waku/message-encryption.md +++ b/docs/guides/js-waku/message-encryption.md @@ -209,9 +209,9 @@ await subscription.subscribe([encoder], callback); ## Storing encryption keys -We used randomly generated keys for encryption and message signing in the provided examples, but real-world applications require consistent keys among clients. Have a look at the [Key Pair Handling](https://github.com/waku-org/js-waku-examples/tree/master/examples/eth-pm/src/key_pair_handling) example, which demonstrates the secure storage and retrieval of key information from local storage using [Subtle Crypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto). +We used randomly generated keys for encryption and message signing in the provided examples, but real-world applications require consistent keys among client restarts. Have a look at the [Key Pair Handling](https://github.com/waku-org/js-waku-examples/tree/master/examples/eth-pm/src/key_pair_handling) example, which demonstrates the secure storage and retrieval of key information from local storage using [Subtle Crypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto). -You can also use the [@waku/utils](https://www.npmjs.com/package/@waku/utils) package to store keys in hexadecimal format: +If you need a simple way to store your keys in hexadecimal format across your application, you can use the [@waku/utils](https://www.npmjs.com/package/@waku/utils) package: ```js import { bytesToHex, hexToBytes } from "@waku/utils/bytes"; From fab54ea06dbd41cff5393f8a09b756ca8d3a2e32 Mon Sep 17 00:00:00 2001 From: LordGhostX Date: Thu, 11 Jan 2024 10:30:57 +0100 Subject: [PATCH 12/12] remove verifySignature till deployment --- docs/guides/js-waku/message-encryption.md | 14 ++++++++++---- docs/learn/waku-network.md | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/guides/js-waku/message-encryption.md b/docs/guides/js-waku/message-encryption.md index 83abc3d0..88a3c37f 100644 --- a/docs/guides/js-waku/message-encryption.md +++ b/docs/guides/js-waku/message-encryption.md @@ -171,11 +171,15 @@ await subscription.subscribe([ECIESEncoder], callback); await node.lightPush.send(ECIESEncoder, { payload }); ``` -You can extract the `signature` and its public key (`signaturePublicKey`) from the [DecodedMessage](https://js.waku.org/classes/_waku_message_encryption.DecodedMessage.html) and compare it with the expected public key or use the `verifySignature()` function to verify the message origin: +You can extract the `signature` and its public key (`signaturePublicKey`) from the [DecodedMessage](https://js.waku.org/classes/_waku_message_encryption.DecodedMessage.html) and compare it with the expected public key to verify the message origin: + + + ```js title="Bob (receiver) client" import { generatePrivateKey } from "@waku/message-encryption"; import { createEncoder } from "@waku/message-encryption/symmetric"; +import { equals } from "uint8arrays/equals"; // Generate a random private key for signing messages // For this example, we'll call the receiver of the message Bob @@ -197,7 +201,7 @@ const callback = (wakuMessage) => { // Verify the message was actually signed and sent by Alice // Alice's public key can be gotten from broadcasting or out-of-band methods - if (wakuMessage.verifySignature(alicePublicKey)) { + if (equals(signaturePublicKey, alicePublicKey)) { console.log("This message was signed by Alice"); } else { console.log("This message was NOT signed by Alice"); @@ -230,5 +234,7 @@ const restoredPrivateKey = hexToBytes(privateKeyHex); ``` :::tip Congratulations! -You have successfully encrypted, decrypted, and signed your messages using `Symmetric` and `ECIES` encryption methods. Have a look at the [flush-notes](https://github.com/waku-org/js-waku-examples/tree/master/examples/flush-notes) and [eth-pm](https://github.com/waku-org/js-waku-examples/tree/master/examples/eth-pm) examples for working demos. -::: \ No newline at end of file +You have successfully encrypted, decrypted, and signed your messages using `Symmetric` and `ECIES` encryption methods. Have a look at the [eth-pm](https://github.com/waku-org/js-waku-examples/tree/master/examples/eth-pm) example for a working demo. +::: + + \ No newline at end of file diff --git a/docs/learn/waku-network.md b/docs/learn/waku-network.md index 31f50c09..1e846cd6 100644 --- a/docs/learn/waku-network.md +++ b/docs/learn/waku-network.md @@ -13,7 +13,7 @@ The Waku Network is a shared p2p messaging network that is open-access, useful f If you want to learn more about the Waku Network, the [WAKU2-NETWORK RFC](https://rfc.vac.dev/spec/64/) provides an in-depth look under the hood. :::info -The public Waku Network replaces the previous experimental shared routing layer based on a default pubsub topic (`/waku/2/default-waku/proto`). If your project currently uses this or any other shared pubsub topics, we encourage you to migrate to the public Waku Network with built-in DoS protection, with built-in DoS protection, scalability, and reasonable bandwidth usage. +The public Waku Network replaces the previous experimental shared routing layer based on a default pubsub topic (`/waku/2/default-waku/proto`). If your project currently uses this or any other shared pubsub topics, we encourage you to migrate to the public Waku Network with built-in DoS protection, scalability, and reasonable bandwidth usage. ::: ## Why join the Waku network?