Erstellen Sie einen verschlüsselten End-to-End-Chat mit Seald und PubNub

PubNub Developer Relations - Mar 18 - - Dev Community

Dieser Artikel wurde von einem Dritten, seald, beigesteuert und stellt eine Alternative zu PubNubs eingebauter Verschlüsselung auf Nachrichtenebene vor*.* Er wurde ursprünglich auf Hackernoon veröffentlicht .


Heute wollen wir herausfinden, wie man einenEnde-zu-Ende-verschlüsselten Chat mit Pubnub und dem seald SDK erstellen kann .

Ein voll funktionsfähiges Beispiel für die Verwendung von PubNub und Seald finden Sie hier: https: //github.com/seald/pubnub-example-project

Was ist Pubnub?

PubNub ist ein Echtzeit-Kommunikationsdienst, der in die meisten Anwendungen integriert werden kann. Er ist zuverlässig und skalierbar und kann leicht in die gängigsten Frameworks integriert werden.

Was ist Seald?

Seald.io bietet ein SDK, mit dem Sie ohne kryptografische Vorkenntnisse eine Ende-zu-Ende-Verschlüsselung mit fortgeschrittenen Verwaltungsfunktionen durchführen können . Dieses SDK kann in Web-, Backend-, Mobil- oder Desktop-Anwendungen integriert werden.

Überblick über den Inhalt

  • Warum Ende-zu-Ende-Verschlüsselung?

  • Warum Seald.io anstelle des PubNub-Verschlüsselungshakens verwenden?👀

  • Ziele 🏆

  • Implementierung 🧠

  • Hinzufügen von Ende-zu-Ende-Verschlüsselung mit Seald 🔒💬

  • Schlussfolgerung ✅

Warum sollte man eine Ende-zu-Ende-Verschlüsselung verwenden? 🔒

Die Ende-zu-Ende-Verschlüsselung bietet das höchste Maß an Datenschutz und Sicherheit. Sie ermöglicht die Verschlüsselung sensibler Daten, sobald sie erfasst werden. Durch eine frühzeitige Verschlüsselung wird die Angriffsfläche Ihrer Anwendung verringert. Ein weiterer Vorteil ist, dass Sie genau steuern können, wer auf die Daten zugreifen darf. Dies schützt auch dann, wenn sie nicht in Ihren Zuständigkeitsbereich fallen, z. B. bei Diensten Dritter.

Mit der Ende-zu-Ende-Verschlüsselung behalten Sie jederzeit die Kontrolle, wenn Ihre Daten übertragen werden, wenn sie ruhen und sogar, wenn Sie sie nicht in der Hand haben. Damit bietet sie einen weitaus umfassenderen Schutz als andere Verschlüsselungstechnologien (TLS, Festplattenverschlüsselung, ...).

Wann immer Sie mit einem Fall konfrontiert sind, in dem die Einhaltung von Vorschriften wichtig ist (GDPR, HIPAA, SOC-2,...) oder Sie sensible Daten haben (Medizin, Verteidigung,...), ist eine Ende-zu-Ende-Verschlüsselung ein Muss. Aber auch für alltäglichere Daten ist sie eine gute Praxis. Eine Datenpanne ist ein verheerendes Ereignis, das immer häufiger vorkommt .

Warum Seald.io anstelle des PubNub-Verschlüsselungshakens verwenden? 👀

PubNub SDK bietet einen einfachen Verschlüsselungshaken, der bei der Instanziierung des SDK das Argument cipherKey verwendet. Damit wird sichergestellt, dass alle hochgeladenen Nachrichten verschlüsselt werden , bevor sie gesendet werden. Allerdings müssen Sie die Schlüsselverwaltung selbst übernehmen.

Schwachstellen entstehen nur selten durch die Verschlüsselung selbst, sondern meistens dadurch, dass die Schlüssel durch Schwachstellen im Sicherheitsmodell nach außen dringen.

Seald.io bietet ein robustes, von der ANSSI zertifiziertes Sicherheitsmodell mit Echtzeit-Zugriffskontrolle, Benutzerwiderruf und -wiederherstellung, 2FA und mehr.

Ziele 🏆

Dieser Artikel erklärt Schritt für Schritt, wie man Seald mit PubNub integriert , um den Chat mit Ende-zu-Ende-Verschlüsselung zu sichern. Wir werden eine Beispiel-Messaging-App mit den folgenden Funktionen erstellen:

  • Einzel- und Gruppen-Chaträume.

  • Jedes Mitglied hat einen eigenen Chatraum mit jedem anderen Benutzer.

  • Jeder kann einen Gruppen-Chatraum mit mehreren anderen Benutzern erstellen.

  • Verwendung von Ende-zu-Ende-Verschlüsselung für jede gesendete Nachricht und Datei.

  • Echtzeit-Zugriffsverwaltung für Chats ermöglichen.

Implementierung 🧠

Einrichten eines PubNub-Kontos 👤

Um loszulegen, benötigen Sie ein PubNub-Konto, das Sie hier einrichten können. Sobald du dich auf deinem Dashboard eingeloggt hast, solltest du sehen, dass eine Demo-App mit einem Demo-Keyset erstellt worden ist:

Wählen Sie das Demo-Keyset aus und scrollen Sie zur Registerkarte "Konfiguration". Für unsere Demo müssen wir die Berechtigungen " Dateien" und " Objekte" aktivieren. Für die Objektberechtigung werden wir die folgenden Ereignisse verwenden: Benutzer-Metadaten-Ereignisse, Kanal-Metadaten-Ereignisse undMitglieder-Ereignisse.

Sobald das Keyset erstellt und konfiguriert ist, müssen wir es in unser Frontend kopieren.

Dazu erstellen wir eine JSON-Datei im Ordner src/ mit dem Namen settings.json. Wir werden diese Datei für alle API-Schlüssel verwenden, die wir benötigen. Wir beginnen mit dem PubNub-Schlüsselsatz:

{
  "PUBNUB_PUB_KEY": "pub-c-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "PUBNUB_SUB_KEY": "sub-c-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
Enter fullscreen mode Exit fullscreen mode

Aufbau eines einfachen Chats mit PubNub 💬

Wir werden PubNub für fast alle Backend-Aufgaben verwenden . Unser Backend wird nur die Benutzeranmeldung/-signierung verarbeiten und ein minimalistisches Benutzermodell mit nur einer ID, einem Namen und einer E-Mail verwenden.

Auf der Vorderseite benötigen wir eine kleine Authentifizierungsschnittstelle:

Sobald der Benutzer ein Konto hat, ist das erste, was er braucht, eine Instanz des PubNub SDK.

Um den Benutzer auf Pubnub zu identifizieren, müssen wir eine UUID bereitstellen.

Der Einfachheit halber werden wir die gleiche ID wie in unserem Backend verwenden:

/* frontend/src/App.js */
import settings from './settings.json' // our settings file for API keys
/*
...
*/
const pubnub = new PubNub({
    publishKey: settings.PUBNUB_PUB_KEY,
    subscribeKey: settings.PUBNUB_SUB_KEY,
    uuid: currentUser.id
})
Enter fullscreen mode Exit fullscreen mode

Um unser Backend so einfach wie möglich zu halten, werden wir die Benutzer-Metadaten von PubNub verwenden, um die Benutzerinformationen auszutauschen.

Direkt nach der SDK-Instanziierung rufen wir einfach die PubNub-Funktion setUUIDMetadata auf:

/* frontend/src/App.js */
await pubnub.objects.setUUIDMetadata({
  uuid: currentUser.id,
  data: {
    email: currentUser.emailAddress,
    name: currentUser.name
  }
})
Enter fullscreen mode Exit fullscreen mode

Den Anfangszustand der App erhalten 🌱

Das erste, was wir mit PubNub tun müssen, ist, alle bestehenden Mitglieder abzurufen und sie in unserem lokalen Datenspeicher zu speichern:

/* frontend/src/App.js */
const existingMembers = await pubnub.objects.getAllUUIDMetadata()
dispatch({
  type: SET_USERS,
  payload: {
    users: existingMembers.data.map(u => new User({ id: u.id, name: u.name, emailAddress: u.email }))
  }
})
Enter fullscreen mode Exit fullscreen mode

Jeder Chatraum wird einem PubNub-Kanal entsprechen. Wir werden auch einige Metadaten zu jedem Kanal hinzufügen:

  • ownerId: Die ID des Benutzers, der den Raum erstellt hat.

  • one2one: Ein Boolescher Wert zur Unterscheidung von Direktnachrichtenräumen und Gruppenräumen.

  • archiviert: Ein Boolescher Wert, um einen gelöschten Gruppenraum auszublenden.

Die ownerId Metadaten werden später beim Hinzufügen des Seald SDK verwendet. PubNub hat kein Eigentumskonzept, aber Seald schon. Es definiert, wer Benutzer zu einem Kanal hinzufügen oder aus ihm entfernen kann. Es definiert im Grunde einen Gruppenadministrator.

Wir beginnen damit, bestehende Chat-Räume abzurufen. Wir benötigen auch die Raum-Metadaten, also müssen wir benutzerdefinierte Felder einfügen. Dann müssen wir archivierte Räume herausfiltern und alles an unseren Datenspeicher senden.

Schließlich abonnieren wir den mit dem Raum verbundenen PubNub-Kanal, damit wir neue Nachrichten erhalten:

/* frontend/src/App.js */
// Retrieve rooms of which we are members
const memberships = await pubnub.objects.getMemberships({
  include: {
    customChannelFields: true
  }
})
const knownRooms = []
// For each room, retrieve room members
for (const room of memberships.data.filter(r => !r.channel.custom.archived)) {
  const roomMembers = await pubnub.objects.getChannelMembers({ channel: room.channel.id })
  knownRooms.push(new Room({
    id: room.channel.id,
    name: room.channel.name,
    users: roomMembers.data.map(u => u.uuid.id),
    ownerId: room.channel.custom.ownerId,
    one2one: room.channel.custom.one2one
  }))
}
// Store rooms in our data store
dispatch({
  type: SET_ROOMS,
  payload: {
    rooms: knownRooms
  }
})
// Subscribe to channels to get new messages
pubnub.subscribe({ channels: knownRooms.map(r => r.id) })
Enter fullscreen mode Exit fullscreen mode

Jetzt haben wir alle Räume abgerufen, in denen wir uns befinden. Wir brauchen noch eine letzte Sache, um die Initialisierung der App zu beenden: Wir müssen sicherstellen, dass wir einen One2One-Raum mit jedem anderen Mitglied haben, einschließlich der neu registrierten.

Für jeden neu gefundenen Benutzer werden wir einen neuen Raum erstellen und eine Hallo-Nachricht senden.

Dann werden wir die Metadaten des Raums einstellen und ihn abonnieren:

/* frontend/src/App.js */
// Ensure that we have a one2one room with everyone
const one2oneRooms = knownRooms.filter(r => r.one2one)
for (const m of existingMembers.data.filter(u => u.id!== currentUser.id)) {
    if (!one2oneRooms.find(r => r.users.includes(m.id))) {
      // New user found: generating a new one2one room
      const newRoomId = PubNub.generateUUID()
      const newRoom = new Room({
            id: newRoomId,
            users: [currentUser.id, m.id],
            one2one: true,
            name: m.name,
            ownerId: currentUser.id
          })
      // Add the new room to our local list
      dispatch({
        type: EDIT_OR_ADD_ROOM,
        payload: {
          room: new Room({
            id: newRoomId,
            users: [currentUser.id, m.id],
            one2one: true,
            name: m.name, ownerId: currentUser.id
          })
        }
      })
      // Publish a "Hello" message in the room
      await pubnub.publish({
        channel: newRoomId,
        message: {
          type: 'message',
          data: (await sealdSession.encryptMessage('Hello 👋'))
        }
      })
      // Subscribe to the new room
      pubnub.subscribe({ channels: [newRoomId] })
      await pubnub.objects.setChannelMetadata({
        channel: newRoomId,
        data: {
          name: 'one2one',
          custom: {
            one2one: true,
            ownerId: currentUser.id,
          },
        }
      })
      await pubnub.objects.setChannelMembers({
        channel: newRoomId,
        uuids: [currentUser.id, m.id]
      })
    }
}
Enter fullscreen mode Exit fullscreen mode

Wenn das alles erledigt ist, ist unser anfänglicher App-Status vollständig definiert. Wir müssen ihn jedoch auf dem neuesten Stand halten.

Das geht ganz einfach, indem wir einen Event-Listener für Mitgliedschaftsereignisse hinzufügen:

/* frontend/src/App.js */
pubnub.addListener({
  objects: async function(objectEvent) {
    if (objectEvent.message.type === 'membership') {
      if (objectEvent.message.event === 'delete') { // User is removed from a room
        /*
        Removing the room from store...
        */
      }
      if (objectEvent.message.event === 'set') { // User is added to a room
        const metadata = await pubnub.objects.getChannelMetadata({ channel: objectEvent.message.data.channel.id })
        const roomMembers = (await pubnub.objects.getChannelMembers({ channel: objectEvent.message.data.channel.id })).data.map(u => u.uuid.id)
        /*
        Adding new room to store + subscribing to new room channel...
        */
      }
    }
  }
})
pubnub.subscribe({ channels: [currentUser.id] }) // channel on which events concerning the current user are published
Enter fullscreen mode Exit fullscreen mode

Wir können uns nun einen one2one-Chatraum selbst ansehen. Dann werden wir Gruppenräume behandeln.

Empfangen und Senden von Nachrichten in einem Chatraum 📩

In einer chat.js-Datei finden wir die gesamte Logik zur Anzeige der Nachrichten eines Chat-Raums.

Um diesen Raum zu initialisieren, müssen wir nur alle bereits existierenden Nachrichten abrufen.

Dazu müssen wir nur die Raum-ID kennen:

/* frontend/src/components/Chat.jsx */
const fetchedMessages = (await pubnub.fetchMessages({ channels: [currentRoomId] })).channels[currentRoomId]
Enter fullscreen mode Exit fullscreen mode

Wir können den Kanal abonnieren, um neue Nachrichten zu erhalten, und einen Listener hinzufügen, um sie in Echtzeit anzuzeigen:

/* frontend/src/components/Chat.jsx */
pubnub.addListener({ message: handleReceiveMessage })
pubnub.subscribe({ channels: [currentRoomId] })
Enter fullscreen mode Exit fullscreen mode

Um eine Nachricht zu senden, müssen wir sie einfach auf dem Kanal veröffentlichen:

/* frontend/src/components/Chat.jsx */
const handleSubmitMessage = async e => {
  /* Some checks that the room is in a correct state... */
  await pubnub.publish({
    channel: state.room.id,
    message: {
      type: 'message',
      data: state.message
    }
  })
}
Enter fullscreen mode Exit fullscreen mode

Um eine Datei zu senden, laden wir sie zunächst auf PubNub hoch. Dann erhalten wir die URI der hochgeladenen Datei und veröffentlichen sie als Nachricht im Chatraum:

/* frontend/src/components/UploadButton.jsx */
// Upload Encrypted file
const uploadData = await pubnub.sendFile({
  channel: room.id,
  file: myFile,
  storeInHistory: false
})
const fileURL = await pubnub.getFileUrl({ id: uploadData.id, name: uploadData.name, channel: room.id })
await pubnub.publish({
  channel: state.room.id,
  message: {
    type: 'file',
    url: fileURL,
    fileName: await sealdSession.encryptMessage(selectedFiles[0].name)
  }
})
Enter fullscreen mode Exit fullscreen mode

Verwaltung von Gruppenchats 👨‍👩‍👦‍👦

Um Gruppen zu erstellen und zu verwalten, benötigen wir eine Schnittstelle für die Auswahl von Benutzern:

Sobald die Gruppenmitglieder ausgewählt sind, können wir einen PubNub-Kanal für unseren Raum erstellen und dann Metadaten und Mitgliedschaft für den Kanal festlegen. Der Code ist dem für one2one-Räume sehr ähnlich, daher werden wir ihn hier nicht wiederholen.

Wir haben jetzt eine vollständige Chat-App. Fügen wir nun eine Ende-zu-Ende-Verschlüsselung für jede Nachricht hinzu!

Hinzufügen von Ende-zu-Ende-Verschlüsselung mit Seald 🔒💬

Einrichten eines Seald-Kontos 👤

Um mit Seald zu beginnen, erstellen Sie hier ein kostenloses Testkonto

Wenn Sie auf dem Seald-Dashboard landen, werden einige URLs und API-Tokens angezeigt.

Holen Sie sich die folgenden Elemente:

  • appId

  • apiURL

  • keyStorageURL

Wir werden diese Schlüssel zu unserer settings.json hinzufügen:

{
  "PUBNUB_PUB_KEY": "pub-c-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "PUBNUB_SUB_KEY": "sub-c-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "SEALD_APP_ID": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "SEALD_API_URL": "https://api.staging-0.seald.io",
  "SEALD_KEYSTORAGE_URL": "https://ssks.staging-0.seald.io"
}
Enter fullscreen mode Exit fullscreen mode

Um das Seald SDK nutzen zu können, benötigt jeder Nutzer bei der Anmeldung ein Lizenz-JWT.

Diese JWT muss im Backend unter Verwendung eines Geheimnisses und einer geheimen ID generiert werden.

Kopieren Sie auf der Dashboard-Landingpage das JWT-Geheimnis und die dazugehörige ID in backend/settings.json:

{
  "SEALD_JWT_SECRET_ID": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
  "SEALD_JWT_SECRET": "XXXXXXXXXXXXXXXXXXXXXXXX"
}
Enter fullscreen mode Exit fullscreen mode

Während des Aufrufs der Anmelde-API wird ein JWT für die Seald-Lizenz generiert und zurückgegeben:

/* backend/routes/account.js */
const token = new SignJWT({
  iss: settings.SEALD_JWT_SECRET_ID,
  jti: uuidv4(), /// Random string with enough entropy to never repeat.
  iat: Math.floor(Date.now() / 1000), // JWT valid only for 10 minutes. `Date.now()` returns the  in milliseconds, this needs it in seconds.
  scopes: [3], // PERMISSION_JOIN_TEAM
  join_team: true
})
  .setProtectedHeader({ alg: 'HS256' })
const signupJWT = await token.sign(Buffer.from(settings.SEALD_JWT_SECRET, 'ascii'))
Enter fullscreen mode Exit fullscreen mode

Weitere Informationen hierzu finden Sie in unserem Dokumentationsartikel über JWT.

Dann müssen wir das Seald SDK installieren.

Außerdem müssen wir ein Plugin installieren, um Benutzer auf dem Seald-Server zu identifizieren. Dazu verwenden wir das Paket sdk-plugin-ssks-password.

Dieses Plugin ermöglicht eine einfache Passwort-Authentifizierung unserer Benutzer:

npm i -S @seald-io/sdk @seald-io/sdk-plugin-ssks-password
Enter fullscreen mode Exit fullscreen mode

Instanziierung des Seald SDK 💡

Anschließend erstellen wir eine Datei seald.js. In dieser Datei erstellen wir zunächst eine Funktion zur Instanziierung des Seald SDK:

/* frontend/src/services/seald.js */
import SealdSDK from '@seald-io/sdk-web'
import SealdSDKPluginSSKSPassword from '@seald-io/sdk-plugin-ssks-password'
import settings from './settings.json'
let sealdSDKInstance = null
const instantiateSealdSDK = async () => {
  sealdSDKInstance = SealdSDK({
    appId: settings.SEALD_APP_ID,
    apiURL: settings.SEALD_API_URL,
    plugins: [SealdSDKPluginSSKSPassword(settings.SEALD_KEYSTORAGE_URL)]
  })
}
Enter fullscreen mode Exit fullscreen mode

Erstellen und Abrufen von Seald-Identitäten 🔑

In seald.js fügen wir außerdem zwei Funktionen hinzu: eine zum Erstellen einer Identität und eine zum Abrufen einer Identität. Um eine Identität zu erstellen, benötigen wir auch den Lizenz-JWT, der bei der Kontoerstellung zurückgegeben wird:

/* frontend/src/services/seald.js */
export const createIdentity = async ({ userId, password, signupJWT }) => {
  await instantiateSealdSDK()
  await sealdSDKInstance.initiateIdentity({ signupJWT })
  await sealdSDKInstance.ssksPassword.saveIdentity({ userId, password })
}
export const retrieveIdentity = async ({ userId, password }) => {
  await instantiateSealdSDK()
  await sealdSDKInstance.ssksPassword.retrieveIdentity({ userId, password })
}
Enter fullscreen mode Exit fullscreen mode

Während unserer Anmelde- und Anmeldeströme müssen wir diese Funktionen nur aufrufen, nachdem sich der Benutzer angemeldet hat.

Zu diesem Zeitpunkt hat unser Benutzer jedes Mal, wenn er verbunden ist, ein funktionierendes Seald SDK, bereit zum Ver- und Entschlüsseln!

Warnung: Um die Sicherheit zu gewährleisten, sollte das Passwort vor dem Senden an den Authentifizierungsserver gehasht werden. Weitere Einzelheiten hierzu finden Sie im Abschnitt über die Passwortauthentifizierung in unserer Dokumentation.

Starten Sie die Ver- und Entschlüsselung von Nachrichten 🔒🔓

Jeder Chatraum wird mit einer encryptionSession auf dem Seald SDK verbunden.

Jedes Mal, wenn wir einen Chatraum erstellen, müssen wir lediglich eine Zeile hinzufügen, um die Verschlüsselungssitzung zu erstellen und sie dann zu verwenden:

/* frontend/src/App.js */
// Create a Seald session
const sealdSession = await getSealdSDKInstance().createEncryptionSession(
  { userIds: [currentUser.id, m.id] },
  { metadata: newRoomId }
)
// Publish a "Hello" message in the room
await pubnub.publish({
  channel: newRoomId,
  message: {
    type: 'message',
    data: (await sealdSession.encryptMessage('Hello 👋'))
  }
})
Enter fullscreen mode Exit fullscreen mode

Beachten Sie, dass unser Benutzer standardmäßig als Empfänger der encryptionSession enthalten ist .

Wenn wir auf einen Raum zugreifen, müssen wir die entsprechende encryptionSession abrufen. Sie kann aus jeder verschlüsselten Nachricht oder Datei abgerufen werden. Sobald wir sie haben, behalten wir sie in der Komponentenreferenz.

Dann können wir einfach die Funktionen session.encryptMessage, session.encryptFile, session.decryptMessage und session.decryptFile verwenden.

Lassen Sie uns mit den Nachrichten beginnen. Um eine Nachricht zu senden:

/* frontend/src/components/Chat.js */
const handleSubmitMessage = async m => {
  /* Some validation that we are in a valid room... */
  // if there is no encryption session set in cache yet, create one
  // (should never happen, as a "Hello" is sent on room creation)
  if (!sealdSessionRef.current) {
    sealdSessionRef.current = await getSealdSDKInstance().createEncryptionSession(
      { userIds: state.room.users },
      { metadata: state.room.id }
    )
  }
  // use the session to encrypt the message we are trying to send
  const encryptedMessage = await sealdSessionRef.current.encryptMessage(state.message)
  // publish the encrypted message to pubnub
  await pubnub.publish({
    channel: state.room.id,
    message: {
      type: 'message',
      data: encryptedMessage
    }
  })
  /* Some cleanup... */
}
Enter fullscreen mode Exit fullscreen mode

Und wenn wir eine Nachricht erhalten:

/* frontend/src/components/Chat.js */
const decryptMessage = async m => {
  /* Filter out files... */
  let encryptedData = m.message.data
  if (!sealdSessionRef.current) { // no encryption session set in cache yet
    // we try to get it by parsing the current message
    sealdSessionRef.current = await getSealdSDKInstance().retrieveEncryptionSession({ encryptedMessage: encryptedData })
    // now that we have a session loaded, let's decrypt
  }
  const decryptedData = await sealdSessionRef.current.decryptMessage(encryptedData)
  // we have successfully decrypted the message
  return {
    ...m,
    uuid: m.uuid || m.publisher,
    value: decryptedData
  }
  /* Some error handling... */
}
/* Other stuff... */
const handleReceiveMessage = async m => {
  const decryptedMessage = await decryptMessage(m)
  setState(draft => {
    draft.messages = [...draft.messages, decryptedMessage]
  })
}
Enter fullscreen mode Exit fullscreen mode

Außerdem verwenden wir diese Funktion decryptMessage, um alle Nachrichten zu entschlüsseln, die sich bereits in der Sitzung befinden, wenn wir einen Raum öffnen:

/* frontend/src/components/Chat.js */
const fetchedMessages = (await pubnub.fetchMessages({ channels: [currentRoomId] })).channels[currentRoomId]
const clearMessages = fetchedMessages ? await Promise.all(fetchedMessages.map(decryptMessage)) : []
Enter fullscreen mode Exit fullscreen mode

Und nun zu den Dateien. Um eine Datei hochzuladen:

/* frontend/src/components/UploadButton.js */
// Encrypt file
const encryptedBlob = await sealdSession.encryptFile(
  selectedFiles[0],
  selectedFiles[0].name,
  { fileSize: selectedFiles[0].size }
)
const encryptedFile = new File([encryptedBlob], selectedFiles[0].name)
// Upload Encrypted file
const uploadData = await pubnub.sendFile({
  channel: room.id,
  file: encryptedFile,
  storeInHistory: false
})
Enter fullscreen mode Exit fullscreen mode

Und um eine Datei zu entschlüsseln:

/* frontend/src/components/Message.js */
const onClick = async () => {
  if (state.data.type === 'file') {
    const response = await fetch(state.data.url)
    const encryptedBlob = await response.blob()
    const { data: clearBlob, filename } = await sealdSession.decryptFile(encryptedBlob)
    const href = window.URL.createObjectURL(clearBlob)
    /* Create an <a> element and simulate a click on it to download the created objectURL */
  }
}
Enter fullscreen mode Exit fullscreen mode

Gruppenmitglieder verwalten 👨‍👩‍👦

Gruppenchats haben auch ihre encryptionSession. Jedes Mal, wenn eine Gruppe erstellt wird, müssen wir eine erstellen:

/* frontend/src/components/ManageDialogRoom.js.js */
// To create the encryptionSession
const sealdSession = await getSealdSDKInstance().createEncryptionSession(
  { userIds: dialogRoom.selectedUsersId },
  { metadata: newRoomId }
)
Enter fullscreen mode Exit fullscreen mode

Dann müssen wir jedes Mal, wenn wir Gruppenmitglieder ändern, diese hinzufügen oder aus der Gruppe entfernen:

/* frontend/src/components/ManageDialogRoom.js.js */
// we compare old and new members to figure out which ones were just added or removed
const usersToRemove = dialogRoom.room.users.filter(id => !dialogRoom.selectedUsersId.includes(id))
const usersToAdd = dialogRoom.selectedUsersId.filter(id => !dialogRoom.room.users.includes(id))
if (usersToAdd.length > 0) {
  // for every added user, add them to the Seald session
  await dialogRoom.sealdSession.addRecipients({ userIds: usersToAdd })
  // then add them to the pubnub channel
  await pubnub.objects.setChannelMembers({
    channel: dialogRoom.room.id,
    uuids: usersToAdd
  })
}
if (usersToRemove.length > 0) {
  // for every removed user, revoke them from the Seald session
  await dialogRoom.sealdSession.revokeRecipients({ userIds: usersToRemove })
  // then remove them from the pubnub channel
  for (const u of usersToRemove) {
    await pubnub.objects.removeMemberships({
      channels: [dialogRoom.room.id],
      uuid: u
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

Schlussfolgerung ✅

Wenn das erledigt ist, sind wir fertig!

Wir haben es geschafft, Seald mit nur ein paar Zeilen Code in PubNub zu integrieren.

Da der Chat nun Ende-zu-Ende-verschlüsselt ist, können Sie Ihren Nutzern versichern, dass ihre Daten vertraulich bleiben, selbst im Falle von Datenschutzverletzungen.

Wie immer, zögern Sie nicht, Seald zu kontaktieren oder PubNub zukontaktieren, wenn Sie zusätzliche Hilfe benötigen.

Wir können es kaum erwarten, zu sehen, was Sie gebaut haben 🥳.

Inhalt

InhaltsübersichtWarum eineEnde-zu-Ende-Verschlüsselung verwenden? 🔒WarumSeald.io anstelle des PubNub-Verschlüsselungshakens verwenden? 👀Ziele🏆Implementierung🧠Einrichten eines PubNub-Kontos 👤Aufbaueines grundlegenden Chats mit PubNub 💬Erstellen desanfänglichen App-Status 🌱Empfangenund SendenvonNachrichten in einem Chatraum 📩Verwaltung einesGruppenchats👨‍👩‍👦‍👦Adding Ende-zu-EndeEnde-zu-Ende-Verschlüsselung mit Seald 🔒💬Einrichteneines Seald-Kontos 👤Initialisierungdes Seald SDK 💡Erstellenund Abrufen von Seald-Identitäten 🔑Starten derVer- und Entschlüsselung von Nachrichten 🔒🔓Verwaltung vonGruppenmitgliedern👨‍👩‍👦Conclusion ✅

Wie kann PubNub Ihnen helfen?

Dieser Artikel wurde ursprünglich auf PubNub.com veröffentlicht.

Unsere Plattform hilft Entwicklern bei der Erstellung, Bereitstellung und Verwaltung von Echtzeit-Interaktivität für Webanwendungen, mobile Anwendungen und IoT-Geräte.

Die Grundlage unserer Plattform ist das größte und am besten skalierbare Echtzeit-Edge-Messaging-Netzwerk der Branche. Mit über 15 Points-of-Presence weltweit, die 800 Millionen monatlich aktive Nutzer unterstützen, und einer Zuverlässigkeit von 99,999 % müssen Sie sich keine Sorgen über Ausfälle, Gleichzeitigkeitsgrenzen oder Latenzprobleme aufgrund von Verkehrsspitzen machen.

PubNub erleben

Sehen Sie sich die Live Tour an, um in weniger als 5 Minuten die grundlegenden Konzepte hinter jeder PubNub-gestützten App zu verstehen

Einrichten

Melden Sie sich für einen PubNub-Account an und erhalten Sie sofort kostenlosen Zugang zu den PubNub-Schlüsseln

Beginnen Sie

Mit den PubNub-Dokumenten können Sie sofort loslegen, unabhängig von Ihrem Anwendungsfall oder SDK

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .