Skip to main content
Bate-papos em grupo usam o mesmo modelo de criptografia do X Chat 1:1: uma chave de conversa compartilhada pelos membros, empacotada para a chave pública de identidade de cada membro, com mensagens criptografadas e assinadas pelo Chat XDK. O que muda é a composição de membros, como você cria a conversa e, muitas vezes, campos de título/avatar criptografados na conversa. Fluxos 1:1 estão em Primeiros passos. Detalhes de endpoints estão em Referência da API → Conversas e mensagens.

Como os grupos diferem de 1:1

A criptografia continua sendo: Chat XDK para chaves e payloads; API do X para criar o grupo, publicar os empacotamentos de chave dos participantes, enviar mensagens e carregar eventos.

Crie o grupo e estabeleça as chaves

  1. Gere o ID do grupo com POST /2/chat/conversations/group/initialize — o data.conversation_id da resposta é o ID com prefixo g que você usará em todos os passos abaixo.
  2. Carregue a chave pública de identidade de cada membro e o public_key_version (rotas GET de chave pública em Chaves de criptografia; GET /2/users/public_keys busca vários usuários em uma requisição). Verifique cada registro com verify_key_binding antes de usá-lo (veja o aviso em Primeiros passos).
  3. Execute prepare_group_create uma vez, com todos os membros (incluindo você), o ID com prefixo g e as listas de IDs de membros/administradores. Uma chamada gera a chave da conversa, empacota-a para cada membro e assina a criação com a identidade da sessão de set_identity — retorna duas assinaturas de ação (a mudança de chave da conversa e a criação do grupo).
  4. POST /2/chat/conversations/group com os membros/administradores do grupo, conversation_key_version, conversation_participant_keys (SDK encrypted_key → API encrypted_conversation_key) e ambas as action_signatures. Falhas de validação vêm como mensagens estáveis e legíveis, 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. Guarde a chave da conversa em bruto e a versão para criptografia/descriptografia.
prepare_group_create assina o title e a avatar_url que você passa e os incorpora literalmente no evento group-create. O servidor compara isso com sua requisição, então os valores de group_name / group_avatar_url no corpo do POST devem ser byte-idênticos ao que você passou ao 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 Primeiros passos — chaves de conversa. Quando a composição mudar, chame prepare_group_members_change com os novos IDs de membros mais a lista atual (membros, administradores, membros pendentes e o título/avatar/TTL atuais, se definidos). Ele rotaciona a chave da conversa e, assim como group-create, retorna duas assinaturas de ação — faça POST de tudo isso para add members (POST /2/chat/conversations/{id}/members). Depois, espere tráfego de mudança de chave: trate-o como rotação de chave em Primeiros passos (extract_conversation_keys / decrypt_events e depois criptografe com a versão mais recente). Como prepare_group_members_change gera uma chave de conversa nova empacotada apenas para os membros que você passa, novos membros recebem a nova versão da chave e não conseguem descriptografar mensagens enviadas com versões anteriores. O contrário não é verdadeiro: a rotação nunca revoga o acesso a versões anteriores — qualquer pessoa que já possua uma chave antiga ainda pode ler as mensagens criptografadas com 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 da conversa (por exemplo o nome de exibição ou a URL do avatar) podem chegar criptografados sob a chave da conversa. Isso não é encrypt_message; é o par genérico encrypt / decrypt do Chat XDK (string UTF-8 na entrada, texto cifrado em base64 na saída, com a chave da conversa em bruto). Se um determinado 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 da conversa não existe até essa chamada gerá-la, então um título no momento da criação não pode ser criptografado com ela). Ao ler 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 da 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 forem sempre reescritos na rotação).

Mensagens e eventos

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

Mudanças de chave por membros que saíram

Os eventos de mudança de chave de um grupo são assinados por quem os realizou — muitas vezes o criador ou um administrador. Se esse membro depois sair do grupo (ou desativar a conta), os endpoints de chaves públicas param de retornar suas chaves, então o caminho de descriptografia verificado (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:
  • Somente 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 tem sua assinatura verificada contra o próprio remetente, então a autoria da mensagem não é afetada
Mantenha o caminho verificado primeiro: 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 rejeitar.

Checklist

  1. Gere o ID com prefixo g com POST /2/chat/conversations/group/initialize
  2. prepare_group_create com todos os membros; faça POST dos empacotamentos 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 nos 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 os metadados do grupo com decrypt quando os campos forem texto cifrado
  6. Envie/receba com os mesmos padrões de 1:1