Skip to main content
Los chats de grupo usan el mismo modelo de cifrado que un X Chat 1:1: una clave de conversación compartida por los miembros, envuelta hacia la clave pública de identidad de cada miembro, con mensajes cifrados y firmados por el Chat XDK. Lo que cambia es la membresía, cómo creas la conversación y, a menudo, los campos de título/avatar cifrados en la conversación. Los flujos 1:1 están en Primeros pasos. Los detalles de los endpoints están bajo API reference → Conversations and messages.

En qué se diferencian los grupos de los 1:1

La criptografía sigue siendo: Chat XDK para claves y cargas útiles; X API para crear el grupo, publicar los envoltorios de clave para los participantes, enviar mensajes y cargar eventos.

Crea el grupo y establece las claves

  1. Genera el id de grupo con POST /2/chat/conversations/group/initialize — el data.conversation_id de la respuesta es el id con prefijo g que usas en todo lo que sigue.
  2. Carga la clave pública de identidad y el public_key_version de cada miembro (rutas GET de claves públicas bajo Encryption keys; GET /2/users/public_keys obtiene varios usuarios en una sola solicitud). Verifica cada registro con verify_key_binding antes de usarlo (consulta la advertencia en Primeros pasos).
  3. Ejecuta prepare_group_create una vez, con todos los miembros (incluyéndote a ti mismo), el id con prefijo g y las listas de ids de miembros/administradores. Una sola llamada genera la clave de conversación, la envuelve para cada miembro y firma la creación — devuelve dos firmas de acción (el cambio de clave de conversación y la creación del grupo).
  4. POST /2/chat/conversations/group con los miembros/administradores del grupo, conversation_key_version, conversation_participant_keys (SDK encrypted_key → API encrypted_conversation_key) y ambas action_signatures. Los fallos de validación regresan como mensajes estables y legibles, por ejemplo "Too many members: adding these members would exceed the allowed group size." o "Cannot add all members: one or more of the requested members cannot be added to this conversation.".
  5. Conserva la clave de conversación en bruto y la versión para cifrar/descifrar.
El title y el avatar_url que pasas a prepare_group_create se firman y se incrustan textualmente en el evento de creación del grupo, y el servidor los compara con la solicitud — así que los valores group_name / group_avatar_url en el cuerpo del POST deben ser byte a byte idénticos a lo que pasaste al SDK, o la llamada falla la validación de firma.
El mapeo del cuerpo para las claves de participantes y las firmas de acción (message_id, encoded_message_event_detail, message_event_signature anidado) es el mismo que el POST de claves en Primeros pasos — claves de conversación. Cuando cambia la membresía, llama a prepare_group_members_change con los nuevos ids de miembros más el roster actual (miembros, administradores, miembros pendientes y el título/avatar/TTL actual si está configurado). Rota la clave de conversación y, al igual que la creación de grupo, devuelve dos firmas de acción — envía todo con POST a add members (POST /2/chat/conversations/{id}/members). Después espera tráfico de cambio de clave: trátalo como la rotación de claves en Primeros pasos (extract_conversation_keys / decrypt_events, luego cifra con la versión más reciente). Como prepare_group_members_change genera una clave de conversación nueva envuelta solo para el roster que pasas, los nuevos miembros reciben la nueva versión de la clave y no pueden descifrar los mensajes enviados bajo versiones anteriores. Lo inverso no es cierto: la rotación nunca revoca el acceso a versiones anteriores — cualquiera que ya tenga una clave vieja puede seguir leyendo los mensajes cifrados con ella. Si sospechas que una clave de conversación fue expuesta, rota con prepare_conversation_key_change; esto protege únicamente los mensajes futuros.

Metadatos de grupo cifrados

Algunos campos de conversación (por ejemplo el nombre para mostrar o la URL del avatar) pueden llegar cifrados con la clave de conversación. Eso no es encrypt_message; es el par genérico encrypt / decrypt del Chat XDK (cadena UTF-8 de entrada, texto cifrado base64 de salida, con la clave de conversación en bruto). Si un campo dado se almacena cifrado lo decide el cliente que lo escribe: prepare_group_create firma y envía el título exactamente como se lo proporcionas (la clave de conversación no existe hasta que esa llamada la genera, así que un título en el momento de la creación no puede cifrarse con ella). Cuando lees una conversación cuyos campos son texto cifrado, descífralos con decrypt y la versión de clave que estaba activa cuando el campo se escribió.
Usa la versión actual de la clave de conversación que aplica a esos metadatos. Si las claves rotaron, descifra con la versión que estaba activa cuando el campo se escribió (o sigue las reglas del producto si los metadatos siempre se reescriben en la rotación).

Mensajes y eventos

Enviar y recibir en un grupo es lo mismo que en un 1:1 una vez que tienes la clave de conversación en bruto: Siempre cifra con la versión más reciente de la clave después de una rotación impulsada por cambios de membresía.

Lista de verificación

  1. Genera el id con prefijo g con POST /2/chat/conversations/group/initialize
  2. prepare_group_create con cada miembro; envía con POST los envoltorios de clave de participantes y ambas firmas de acción a POST /2/chat/conversations/group
  3. Cachea la clave en bruto + versión; actualiza en eventos de cambio de clave
  4. En cambios de membresía, prepare_group_members_change (dos firmas) → POST /2/chat/conversations/{id}/members
  5. Descifra los metadatos del grupo con decrypt cuando los campos sean texto cifrado
  6. Envía/recibe con los mismos patrones que en 1:1