Skip to main content
Os chats em grupo usam o mesmo modelo de criptografia do X Chat 1:1: uma chave de conversa compartilhada pelos membros, envelopada para a chave pública de identidade de cada membro, com mensagens criptografadas e assinadas pelo Chat XDK. O que muda é a composição, a forma como você cria a conversa e frequentemente os campos de título/avatar criptografados na conversa. Os fluxos 1:1 estão em Guia de introdução. Detalhes de endpoints estão em Referência da API → Conversas e mensagens.

Como grupos diferem de 1:1

A criptografia ainda é: Chat XDK para chaves e payloads; X API para criar o grupo, publicar envelopes de chave para participantes, enviar mensagens e carregar eventos.

Crie o grupo e estabeleça as chaves

  1. Emita o ID do grupo com POST /2/chat/conversations/group/initialize — o data.conversation_id da resposta é o ID prefixado com g que você usa em todos os passos a seguir.
  2. Carregue a chave pública de identidade e o public_key_version de cada membro (rotas GET de chave pública em Chaves de criptografia; GET /2/users/public_keys busca vários usuários em uma única requisição). Verifique cada registro com verify_key_binding antes de usá-lo (veja o aviso em Guia de introdução).
  3. Execute prepare_group_create uma vez, com todos os membros (incluindo você mesmo), o ID prefixado com g e as listas de IDs de membros/admins. Uma chamada gera a chave de conversa, envelopa-a para cada membro e assina a criação com a identidade da sessão de set_identity — ela retorna duas assinaturas de ação (a mudança de chave de conversa e a criação do grupo).
  4. POST /2/chat/conversations/group com os members/admins do grupo, conversation_key_version, conversation_participant_keys (SDK encrypted_key → API encrypted_conversation_key) e ambas as action_signatures. Falhas de validação retornam mensagens estáveis e legíveis por humanos, por exemplo "Too many members: adding these members would exceed the allowed group size." ou "Cannot add all members: one or more of the requested members cannot be added to this conversation.".
  5. Mantenha a chave de conversa em bruto e a versão para criptografar/descriptografar.
prepare_group_create assina o title e o avatar_url que você passa e os embute literalmente no evento de criação do grupo. O servidor os compara com sua requisição, portanto os valores group_name / group_avatar_url no corpo do POST precisam ser byte a byte idênticos ao que você passou para o SDK — caso contrário, a chamada falha na validação de assinatura.
O mapeamento do corpo para chaves de participantes e assinaturas de ação (message_id, encoded_message_event_detail, message_event_signature aninhado) é o mesmo do POST de chaves em Guia de introdução — chaves de conversa. Quando a composição muda, chame prepare_group_members_change com os novos IDs de membros mais a lista atual (membros, admins, membros pendentes e o título/avatar/TTL atuais, se definidos). Ela rotaciona a chave de conversa e, como a criação de grupo, retorna duas assinaturas de ação — faça POST de tudo em add members (POST /2/chat/conversations/{id}/members). Depois, espere tráfego de mudança de chave: trate-o como a rotação de chave no Guia de introdução (extract_conversation_keys / decrypt_events, depois criptografe com a versão mais recente). Como prepare_group_members_change gera uma nova chave de conversa envelopada apenas para a lista que você passa, novos membros recebem a nova versão da chave e não podem descriptografar mensagens enviadas sob versões anteriores. O inverso não é verdadeiro: a rotação nunca revoga o acesso a versões anteriores — quem já possui uma chave antiga ainda pode ler as mensagens criptografadas sob ela. Se você suspeitar que uma chave de conversa foi exposta, rotacione com prepare_conversation_key_change; isso protege apenas mensagens futuras.

Metadados de grupo criptografados

Alguns campos de conversa (por exemplo, nome de exibição ou URL do avatar) podem chegar criptografados sob a chave de conversa. Isso não é encrypt_message; é o par genérico encrypt / decrypt do Chat XDK (string UTF-8 na entrada, texto cifrado base64 na saída, com a chave de conversa em bruto). Se um dado campo é armazenado criptografado é decidido pelo cliente que o escreve: prepare_group_create assina e envia o título exatamente como você o fornece (a chave de conversa não existe até que essa chamada a gere, então um título no momento da criação não pode ser criptografado sob ela). Quando você lê uma conversa cujos campos são texto cifrado, descriptografe-os com decrypt e a versão de chave que estava ativa quando o campo foi escrito.
Use a versão atual da chave de conversa que se aplica a esse metadado. Se as chaves foram rotacionadas, descriptografe com a versão que estava ativa quando o campo foi escrito (ou siga as regras do produto se os metadados são sempre reescritos na rotação).

Mensagens e eventos

Enviar e receber em um grupo é igual ao 1:1 uma vez que você tem a chave de conversa em bruto: Sempre criptografe com a versão de chave mais recente após uma rotação motivada por mudança de composição.

Mudanças de chave de membros que saíram

Os eventos de mudança de chave de um grupo são assinados por quem os executou — frequentemente o criador ou um admin. Se esse membro depois sair do grupo (ou desativar a conta), os endpoints de chaves públicas param de retornar as chaves dele, então o caminho de descriptografia verificada (decrypt_events com chaves de assinatura) falha nesses eventos de mudança de chave com signature missing or no matching signing key. Os eventos não estão corrompidos; o material de verificação simplesmente não é mais servido. Grupos de longa duração devem prever isso e recorrer a extract_conversation_keys para eventos de mudança de chave que não podem ser verificados. Esse caminho ignora a verificação de assinatura e recupera a chave de conversa descriptografando-a com sua chave de identidade. O modelo de segurança se mantém porque:
  • Apenas o material de chave que foi criptografado para sua chave de identidade pode ser recuperado — um terceiro não pode injetar uma chave que você consiga ler
  • Cada mensagem ainda é verificada por assinatura contra seu próprio remetente, então a autoria das mensagens não é afetada
Mantenha o caminho verificado em primeiro lugar: use decrypt_events (que também alimenta o cache de chaves do SDK quando set_cache_keys(true) está habilitado) e recorra a extract_conversation_keys apenas para os eventos de mudança de chave que ele rejeita.

Checklist

  1. Emita o ID prefixado com g com POST /2/chat/conversations/group/initialize
  2. prepare_group_create com cada membro; POST dos envelopes de chave dos participantes e ambas as assinaturas de ação para POST /2/chat/conversations/group
  3. Faça cache da chave em bruto + versão; atualize em eventos de mudança de chave
  4. Em mudanças de composição, prepare_group_members_change (duas assinaturas) → POST /2/chat/conversations/{id}/members
  5. Descriptografe metadados de grupo com decrypt quando os campos são texto cifrado
  6. Envie/receba com os mesmos padrões do 1:1