그룹이 1:1과 어떻게 다른가
암호화는 여전히 다음과 같습니다: 키와 페이로드를 위한 Chat XDK; 그룹 생성, 참여자 키 감싸기 게시, 메시지 전송, 이벤트 로드를 위한 X API.
그룹 생성 및 키 설정
POST /2/chat/conversations/group/initialize로 그룹 ID를 만드세요—응답의data.conversation_id는 아래 모든 곳에서 사용하는 g가 접두된 ID입니다.- 각 멤버의 아이덴티티 공개 키와
public_key_version을 로드하세요(Encryption keys 아래의GET공개 키 경로;GET /2/users/public_keys는 한 요청으로 여러 사용자를 가져옵니다). 사용하기 전에verify_key_binding으로 각 레코드를 검증하세요(시작하기의 경고 참고). - 모든 멤버(자신 포함), g가 접두된 ID, 멤버/관리자 ID 목록과 함께 **
prepare_group_create**을 한 번 실행하세요. 한 번의 호출로 대화 키를 생성하고, 모든 멤버에게 감싸며,set_identity의 세션 아이덴티티로 create에 서명합니다—두 개의 액션 서명(대화 키 변경과 그룹 create)을 반환합니다. - 그룹 members/admins,
conversation_key_version,conversation_participant_keys(SDKencrypted_key→ APIencrypted_conversation_key), 그리고 두 개 모두의action_signatures와 함께POST /2/chat/conversations/group을 호출하세요. 검증 실패는 안정적이고 사람이 읽을 수 있는 메시지로 돌아옵니다. 예:"Too many members: adding these members would exceed the allowed group size."또는"Cannot add all members: one or more of the requested members cannot be added to this conversation.". - 암호화/복호화를 위해 원시 대화 키와 버전을 보관하세요.
prepare_group_create는 전달한 title과 avatar_url에 서명하여 그룹 생성 이벤트에 원본 그대로 포함시킵니다. 서버는 이를 요청과 대조하므로, POST 본문의 group_name / group_avatar_url 값은 SDK에 전달한 것과 바이트 단위로 동일해야 합니다—그렇지 않으면 호출이 서명 검증에 실패합니다.
- Python
- TypeScript
- Rust
- Go
- C#
- Java
message_id, encoded_message_event_detail, 중첩된 message_event_signature)의 본문 매핑은 시작하기 — 대화 키의 키 POST와 동일합니다.
멤버십이 변경될 때는 새 멤버 ID와 현재 명단(members, admins, pending members, 현재 title/avatar/TTL이 설정되어 있다면 포함)으로 **prepare_group_members_change**를 호출하세요. 이는 대화 키를 순환하고, 그룹 create와 마찬가지로 두 개의 액션 서명을 반환합니다—모두를 add members(POST /2/chat/conversations/{id}/members)에 POST하세요. 그런 다음 키 변경 트래픽을 예상하세요: 시작하기의 키 순환처럼 취급하세요(extract_conversation_keys / decrypt_events, 그 후 최신 버전으로 암호화).
prepare_group_members_change는 전달한 명단에만 감싸진 새로운 대화 키를 생성하므로, 새 멤버는 새 키 버전을 받으며 이전 버전으로 전송된 메시지는 복호화할 수 없습니다. 반대는 성립하지 않습니다: 순환은 이전 버전에 대한 접근을 결코 취소하지 않습니다—오래된 키를 이미 가진 사람은 그 키로 암호화된 메시지를 여전히 읽을 수 있습니다. 대화 키가 노출된 것으로 의심되면 prepare_conversation_key_change로 순환하세요. 이는 미래의 메시지만 보호합니다.
암호화된 그룹 메타데이터
일부 대화 필드(예: 표시 이름 또는 아바타 URL)는 대화 키로 암호화되어 도착할 수 있습니다. 이는encrypt_message가 아닙니다. Chat XDK의 범용 encrypt / decrypt 쌍입니다(UTF-8 문자열 입력, base64 암호문 출력, 원시 대화 키 사용).
특정 필드가 암호화되어 저장될지는 이를 쓰는 클라이언트가 결정합니다: prepare_group_create는 제공한 대로 정확히 title을 서명하고 전송합니다(대화 키는 그 호출이 생성할 때까지 존재하지 않으므로, 생성 시 title은 그 키로 암호화될 수 없습니다). 필드가 암호문인 대화를 읽을 때는, 필드가 작성될 당시 활성화되어 있던 키 버전으로 decrypt를 사용해 복호화하세요.
- Python
- TypeScript
- Rust
- Go
- C#
- Java
메시지와 이벤트
원시 대화 키를 얻은 후 그룹에서의 전송과 수신은 1:1과 동일합니다:- 전송:
encrypt_message→ send-message API(시작하기) - 수신: events API 또는 실시간 전달 →
decrypt_event/decrypt_events - 미디어: 그룹 대화 ID와 함께 미디어
떠난 멤버로부터의 키 변경
그룹의 키 변경 이벤트는 이를 수행한 사람—흔히 생성자 또는 관리자—에 의해 서명됩니다. 해당 멤버가 나중에 그룹을 떠나면(또는 비활성화되면), public-keys 엔드포인트는 그 사람의 키 반환을 중단하므로, 검증된 복호화 경로(서명 키와 함께하는decrypt_events)는 그러한 키 변경 이벤트에서 signature missing or no matching signing key로 실패합니다. 이벤트가 손상된 것이 아니라, 검증에 필요한 자료가 더 이상 제공되지 않을 뿐입니다.
수명이 긴 그룹은 이를 예상하고, 검증할 수 없는 키 변경 이벤트에 대해서는 **extract_conversation_keys**로 폴백해야 합니다. 이 경로는 서명 검사를 건너뛰고, 여러분의 아이덴티티 키로 대화 키를 복호화하여 이를 복구합니다. 다음과 같은 이유로 보안 모델은 유지됩니다:
- 여러분의 아이덴티티 키로 암호화된 키 자료만이 애초에 복구될 수 있습니다—제3자가 여러분이 읽을 수 있는 키를 주입할 수는 없습니다
- 모든 메시지는 여전히 자신의 발신자에 대해 서명 검증되므로, 메시지 작성자 확인에는 영향이 없습니다
decrypt_events(이는 set_cache_keys(true)가 활성화되면 SDK의 키 캐시에도 공급합니다)를 사용하고, 이것이 거부하는 키 변경 이벤트에 대해서만 extract_conversation_keys를 사용하세요.
체크리스트
POST /2/chat/conversations/group/initialize로 g가 접두된 ID를 생성- 모든 멤버와 함께
prepare_group_create; 참여자 키 감싸기와 두 개 모두의 액션 서명을POST /2/chat/conversations/group에 POST - 원시 키 + 버전을 캐시; 키 변경 이벤트에 따라 업데이트
- 멤버십 변경 시
prepare_group_members_change(서명 두 개) →POST /2/chat/conversations/{id}/members - 필드가 암호문인 경우
decrypt로 그룹 메타데이터 복호화 - 1:1과 동일한 패턴으로 송수신