Seald와 PubNub로 엔드투엔드 암호화 채팅 구축하기

PubNub Developer Relations - Mar 18 - - Dev Community

이 글은 타사인 seald에서제공 한 것으로 PubNub에 내장된 메시지 수준 암호화에 대한 대안을 제시합니다 . 원래는 해커눈에 게시되었습니다 .


오늘은 Pubnub과 seald SDK로 엔드투엔드 암호화 채팅을 구축하는 방법에 대해 알아보세요.

PubNub과 Seald를 사용하는 방법에 대한 전체 작동 예제는 여기에서 확인할 수 있습니다: https: //github.com/seald/pubnub-example-project

펍넙이란 무엇인가요?

PubNub은 대부분의 애플리케이션에 통합할 수 있는 실시간 커뮤니케이션 서비스입니다. 안정적이고 확장성이 뛰어나며 가장 일반적인 프레임워크와 쉽게 통합할 수 있습니다.

Seald란 무엇인가요?

Seald.io는 사전 암호화 지식 없이도 고급 관리 기능과 함께 엔드투엔드 암호화를 수행할 수 있는 SDK를 제공합니다. 이 SDK는 웹, 백엔드, 모바일 또는 데스크톱 애플리케이션에 통합할 수 있습니다.

콘텐츠 개요

  • 왜 엔드투엔드 암호화를 사용해야 하나요?

  • PubNub 암호화 후크 대신 Seald.io를 사용해야 하는 이유 👀

  • 목표 🏆

  • 구현 🧠

  • Seald로 엔드투엔드 암호화 추가하기 🔒💬

  • 결론 ✅

왜 엔드투엔드 암호화를 사용해야 하나요? 🔒

엔드투엔드 암호화는 최고 수준의 개인정보 보호 및 보안을 제공합니다. 민감한 데이터를 수집하는 즉시 암호화할 수 있습니다. 조기에 암호화하면 앱의 공격 표면이 줄어듭니다. 또 다른 장점은 데이터에 액세스할 수 있는 사용자를 정확하게 관리할 수 있다는 것입니다. 또한 타사 서비스처럼 사용자의 범위에 속하지 않는 경우에도 보호할 수 있습니다.

엔드투엔드 암호화를 사용하면 데이터가 전송 중일 때, 미사용 중일 때, 심지어 손에 들고 있지 않을 때에도 항상 제어권을 유지할 수 있습니다. 따라서 다른 암호화 기술(TLS, 전체 디스크 암호화 등)보다 훨씬 더 광범위한 보호 기능을 제공합니다.

규정 준수가 중요한 경우(GDPR, HIPAA, SOC-2 등) 또는 민감한 데이터 (의료, 국방 등)가 있는 경우라면 엔드투엔드 암호화는 필수입니다. 하지만 보다 일반적인 데이터의 경우에도 암호화를 사용하는 것이 좋습니다. 데이터 유출은 점점 더 빈번하게 발생하고 있는 파괴적인 사건입니다.

PubNub 암호화 후크 대신 Seald.io를 사용하는 이유는 무엇인가요? 👀

PubNub SDK는 SDK를 인스턴스화할 때 cipherKey 인수를 사용하여 간단한 암호화 훅을 제공합니다. 이렇게 하면 업로드된 모든 메시지가 전송되기 전에 암호화됩니다. 그러나 키 관리는 직접 수행해야 합니다.

취약점은 암호화 자체에서 발생하는 경우는 드물지만 보안 모델의 결함으로 인해 키가 유출되는 경우가 대부분입니다.

보안을 위해 타사 서비스를 사용하면 단일 장애 지점이 발생하지 않습니다. Seald.io는 실시간 액세스 관리 제어, 사용자 해지 및 복구, 2FA 등을 통해 ANSSI의 인증을 받은 강력한 보안 모델을 제안합니다.

목표 🏆

이 문서에서는 엔드투엔드 암호화로 채팅을 보호하기 위해 Seald와 PubNub을 단계별로 통합하는 방법을 설명합니다. 다음 기능을 갖춘 메시징 앱 예시를 구축하겠습니다:

  • 일대일 및 그룹 채팅방.

  • 각 구성원은 다른 모든 사용자와 전용 채팅방을 갖게 됩니다.

  • 누구나 다른 여러 사용자와 함께 그룹 채팅방을 만들 수 있습니다.

  • 모든 메시지와 파일 전송 시 엔드투엔드 암호화를 사용합니다.

  • 채팅에 대한 실시간 액세스 관리를 허용합니다.

구현 🧠

PubNub 계정 설정 👤

시작하려면 PubNub 계정이 필요합니다. 여기에서 가입할 수 있습니다. 대시보드에 로그인하면 데모 키 세트가 포함된 데모 앱이 생성된 것을 볼 수 있습니다:

데모 키셋을 선택하고 구성 탭으로 스크롤합니다. 데모의 경우 파일개체 권한을 활성화해야 합니다. 개체 권한의 경우 사용자 메타데이터 이벤트, 채널 메타데이터 이벤트 및 멤버십이벤트를 사용합니다.

키 세트가 생성되고 구성되면 이를 프런트엔드에 복사해야 합니다.

src/ 폴더에 settings.json이라는 JSON 파일을 만들어 보겠습니다. 이 파일은 필요한 모든 API 키에 사용할 것입니다. PubNub 키셋부터 시작하겠습니다:

{
  "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

PubNub를 사용하여 기본 채팅 구축하기 💬

거의 모든 백엔드 작업에 PubNub을 사용할 것입니다. 백엔드에서는 사용자 가입/로그인만 처리하고 ID, 이름, 이메일만 있는 최소한의 사용자 모델을 사용할 것입니다.

전면에는 작은 인증 인터페이스가 필요합니다:

사용자가 계정을 생성하면 가장 먼저 필요한 것은 PubNub SDK의 인스턴스입니다.

Pubnub에서 사용자를 식별하려면 UUID를 제공해야 합니다.

간단하게 하기 위해 백엔드에서와 동일한 ID를 사용하겠습니다:

/* 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

백엔드를 최대한 단순하게 유지하기 위해 PubNub의 사용자 메타데이터를 사용하여 사용자 정보를 교환할 것입니다.

SDK 인스턴스화 직후 PubNub setUUIDMetadata 함수를 호출하기만 하면 됩니다:

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

초기 앱 상태 가져오기 🌱

PubNub에서가장 먼저 해야 할 일은 기존의 모든 멤버를 검색하여 로컬 데이터 저장소에 저장하는 것입니다:

/* 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

각 채팅방은 PubNub 채널에 해당합니다. 또한 각 채널에 몇 가지 메타데이터를 추가합니다:

  • ownerId: 대화방을 만든 사용자의 ID입니다.

  • one2one: 쪽지 대화방과 그룹 대화방을 구분하기 위한 부울입니다.

  • archived: 삭제된 그룹방을 숨기기 위한 부울입니다.

소유자 ID 메타데이터는 나중에 Seald SDK를 추가할 때 사용됩니다. PubNub에는 소유권 개념이 없지만 Seald에는 소유권 개념이 있습니다. 이 메타데이터는 채널에서 사용자를 추가하거나 제거할 수 있는 사용자를 정의합니다. 기본적으로 그룹 관리자를 정의합니다.

기존 대화방을 검색하는 것부터 시작하겠습니다. 대화방 메타데이터도 필요하므로 사용자 지정 필드를 포함해야 합니다. 그런 다음 보관된 대화방을 필터링하여 모든 것을 데이터 저장소로 보내야 합니다.

마지막으로 해당 대화방과 연결된 PubNub 채널을 구독하여 새 메시지를 수신합니다:

/* 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

이제 우리가 있는 모든 방을 가져왔습니다. 앱 초기화를 완료하기 위해 마지막으로 한 가지 더 필요한 것은 새로 등록된 회원을 포함한 모든 회원과 일대일 방이 있는지 확인하는 것입니다.

새로 찾은 모든 사용자에 대해 새 방을 생성하고 인사 메시지를 보냅니다.

그런 다음, 방의 메타데이터를 설정하고 구독을 신청합니다:

/* 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

이 모든 작업이 완료되면 초기 앱 상태가 완전히 정의됩니다. 하지만 이를 최신 상태로 유지해야 합니다.

이는 멤버십 이벤트에 대한 이벤트 리스너를 추가하면 간단히 수행할 수 있습니다:

/* 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

이제 일대일 채팅방 자체를 살펴볼 수 있습니다. 그런 다음 그룹 대화방을 처리하겠습니다.

채팅방에서 메시지 받기 및 보내기 📩

chat.js 파일에는 채팅방의 메시지를 표시하는 모든 로직이 있습니다.

이 대화방을 초기화하기 위해 필요한 것은 기존의 모든 메시지를 가져오는 것뿐입니다.

이 작업은 대화방 ID만 알면 간단히 수행할 수 있습니다:

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

채널을 구독하여 새 메시지를 받고, 수신자를 추가하여 실시간으로 메시지를 표시할 수 있습니다:

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

메시지를 보내려면 채널에 게시하기만 하면 됩니다:

/* 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

파일을 보내려면 먼저 PubNub에 파일을 업로드합니다. 그런 다음 업로드된 파일 URI를 가져와 채팅방에 메시지로 게시합니다:

/* 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

그룹 채팅 관리하기 👨‍👩‍👦‍👦

그룹을 만들고 관리하려면 사용자를 선택하기 위한 인터페이스가 필요합니다:

그룹 구성원이 선택되면 대화방에 대한 PubNub 채널을 생성한 다음 채널의 메타데이터와 멤버십을 설정할 수 있습니다. 이 코드는 원투원 룸에서 수행되는 것과 매우 유사하므로 여기서는 반복하지 않겠습니다.

이제 전체 채팅 앱이 완성되었습니다. 모든 메시지에 대해 엔드투엔드 암호화를 추가해 보겠습니다!

Seald로 엔드투엔드 암호화 추가하기 🔒💬

Seald 계정 설정하기 👤

Seald를 시작하려면 여기에서 무료 평가판 계정을 만드세요.

Seald 대시보드에 도착하면 몇 개의 URL과 API 토큰이 표시됩니다.

다음 요소를 가져옵니다:

  • 앱아이디

  • apiURL

  • keyStorageURL

이 키를 설정.json에 추가합니다:

{
  "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

Seald SDK를 사용하려면 모든 사용자가 가입할 때 라이선스 JWT가 필요합니다.

이 JWT는 백엔드에서 비밀 번호와 비밀 ID를 사용하여 생성해야 합니다.

대시보드 랜딩 페이지에서 백엔드/settings.json에 JWT 비밀 및 관련 ID를 복사합니다:

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

가입 API 호출 중에 Seald 라이선스 JWT를 생성하고 이를 다시 반환합니다:

/* 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

이에 대한 자세한 내용은 JWT에 대한 문서 문서를 참조하세요.

그런 다음 Seald SDK를 설치해야 합니다.

또한 Seald 서버에서 사용자를 식별하기 위한플러그인도 설치해야 합니다. 이를 위해 sdk-plugin-ssks-password 패키지를 사용합니다.

이 플러그인을 사용하면 간단한 비밀번호 인증을 통해 사용자를 인증할 수 있습니다:

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

Seald SDK 인스턴스화하기 💡

그런 다음 seald.js 파일을 생성합니다. 이 파일에서는 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

Seald ID 생성 및 검색하기 🔑

seald.js에는 ID를 생성하는 함수와 검색하는 함수 두 개를 추가합니다. ID를 생성하려면 계정 생성 시 반환되는 라이선스 JWT도 필요합니다:

/* 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

가입 및 로그인 흐름에서 사용자가 로그인한 후 이 함수를 호출하기만 하면 됩니다.

이 시점에서 사용자가 연결될 때마다 암호화 및 복호화할 준비가 된 작동하는 Seald SDK를 갖게 됩니다 !

경고: 적절한 보안을 위해 비밀번호는 인증 서버로 전송되기 전에 미리 해시 처리해야 합니다. 이에 대한 자세한 내용은 문서에서 비밀번호 인증에 대한 단락을 참조하세요.

메시지 암호화 및 복호화 시작하기 🔒🔓

각 대화방은 Seald SDK의 암호화 세션과 연결됩니다.

대화방을 만들 때마다 한 줄만 추가하여 암호화 세션을 생성한 다음 사용하면 됩니다:

/* 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

사용자는 기본적으로 암호화 세션의 수신자로 포함됩니다.

회의실에 액세스할 때는 해당 encryptionSession을 가져와야 합니다. 이는 암호화된 메시지나 파일에서 검색할 수 있습니다. 일단 확보하면 컴포넌트 참조에 보관합니다.

그런 다음 세션.encryptMessage, 세션.encryptFile, 세션.decryptMessage세션.decryptFile 함수를 간단히 사용할 수 있습니다.

메시지부터 시작해 보겠습니다. 메시지를 보내려면:

/* 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

그리고 메시지를 받을 때

/* 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

또한, 방을 열 때 세션에 이미 있는 모든 메시지를 해독하기 위해 이 decryptMessage 함수를 사용합니다:

/* 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

이제 파일에 대해 알아보겠습니다. 파일을 업로드하려면:

/* 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

그리고 파일의 암호를 해독하려면

/* 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

그룹 구성원 관리하기 👨‍👩‍👦

그룹 채팅에도 암호화 세션이 있습니다. 그룹이 생성될 때마다 그룹을 만들어야 합니다:

/* 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

그런 다음 그룹 구성원을 수정할 때마다 그룹 에서 추가하거나 제거해야 합니다:

/* 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

결론 ✅

이 작업이 완료되면 완료입니다!

몇 줄의 코드만으로 Seald를 PubNub에 통합할 수 있었습니다.

이제 채팅이 엔드투엔드 암호화되었으므로 데이터 유출이 발생하더라도 사용자의 데이터가 기밀로 유지될 것이라는 확신을 줄 수 있습니다.

언제나 그렇듯이 추가 안내가 필요한 경우 주저하지 마시고 Seald에 문의하거나 PubNub( )로 문의해 주세요.

여러분이 구축한 것을 보고 싶어요 🥳.

콘텐츠

콘텐츠개요엔드투엔드 암호화를 사용하는이유는 무엇인가요?PubNub 암호화 후크 대신 Seald.io를 사용하는이유는 무엇인가요?👀목표🏆구현하기🧠PubNub 계정 설정하기👤PubNub을 사용하여 기본 채팅구축하기💬초기 앱 상태가져오기🌱대화방에서 메시지수신및 보내기📩그룹 채팅관리하기👨‍👩‍👦‍👦Adding 종단간엔드 암호화 🔒💬Seal계정설정하기👤SealSDK인스턴스화하기💡Seal ID생성및 검색하기🔑메시지 암호화 및 복호화시작하기🔒🔓그룹 멤버관리하기👨‍👩‍👦Conclusion

펍넙이 어떤 도움을 줄 수 있나요?

이 기사는 원래 PubNub.com에 게시되었습니다.

저희 플랫폼은 개발자가 웹 앱, 모바일 앱, IoT 디바이스를 위한 실시간 상호작용을 구축, 제공, 관리할 수 있도록 지원합니다.

저희 플랫폼의 기반은 업계에서 가장 크고 확장성이 뛰어난 실시간 에지 메시징 네트워크입니다. 전 세계 15개 이상의 PoP가 월간 8억 명의 활성 사용자를 지원하고 99.999%의 안정성을 제공하므로 중단, 동시 접속자 수 제한 또는 트래픽 폭증으로 인한 지연 문제를 걱정할 필요가 없습니다.

PubNub 체험하기

라이브 투어를 통해 5분 이내에 모든 PubNub 기반 앱의 필수 개념을 이해하세요.

설정하기

PubNub 계정에 가입하여 PubNub 키에 무료로 즉시 액세스하세요.

시작하기

사용 사례나 SDK에 관계없이 PubNub 문서를 통해 바로 시작하고 실행할 수 있습니다.

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