Skip to main content
Esta página cubre problemas específicos del cifrado de X Chat y del Chat XDK—claves, copia de seguridad segura de claves, descifrar/verificar y construcción de payloads cifrados de envío. Para webhooks, OAuth, códigos de estado HTTP y límites de tasa, usa la documentación general de la X API y de autenticación.

Claves y copia de seguridad segura de claves

El desbloqueo falla (código de acceso inválido)

  • Confirma que el código de acceso coincide con el usado en setup
  • Espera entre intentos; los realms limitan por tasa los intentos incorrectos y pueden bloquear la recuperación tras demasiados fallos

El cifrado o descifrado falla porque las claves o la identidad no están configuradas

Carga primero las claves privadas y luego establece la identidad de sesión—tu ID de usuario más el public_key_version de tu registro en X. Los métodos encrypt_* y prepare_* firman con ella; llamarlos sin identidad de sesión (y sin una sobrecarga explícita por llamada) es un error.

Tu clave pública local nunca coincide con las claves registradas de la cuenta

A menudo los clientes necesitan responder “¿la clave en este dispositivo es una de las claves registradas para esta cuenta?” — tras una restauración o importación, para adoptar el public_key_version correcto, o para decidir si el onboarding ya ocurrió. Comparar la salida de get_public_keys del Chat XDK contra el campo public_key de la API como cadenas siempre falla, incluso para la misma clave, porque las dos usan codificaciones distintas:
  • La API almacena y devuelve la clave exactamente como la subió el registro: la codificación DER (SPKI) — la clave en bruto detrás de un prefijo fijo de identificador de algoritmo
  • La get_public_keys del Chat XDK devuelve la clave en bruto sola, sin ese prefijo
La misma clave, dos escrituras. Para compararlas, decodifica ambas desde base64 y comprueba que los bytes de la API terminan con los bytes del SDK (bytes idénticos también coinciden, por si ambas partes alguna vez tienen la misma codificación):
Una vez que coincidan, adopta el public_key_version de esa fila para set_identity. Cuando compares versiones (por ejemplo, para elegir la clave más reciente), compara numéricamente — las versiones son marcas de tiempo en milisegundos de longitud de cadena variable, por lo que una comparación lexicográfica elige la incorrecta.

Falta la clave de conversación para un mensaje

Un error como Message encrypted with key version '…' but no matching key found significa que no tienes la clave en bruto para el conversation_key_version de ese mensaje.
  1. Descifra el material de clave desde conversation_key_change_event (eventos en vivo) o meta.conversation_key_events (historial) con extract_conversation_keys, o incluye esos blobs en decrypt_events—con set_cache_keys(true) habilitado, decrypt_events también retiene la clave verificada más reciente de cada conversación para que las llamadas posteriores a decrypt_event y encrypt_* puedan omitirla
  2. Confirma que se agregaron claves de conversación para esa versión y que sigues siendo participante (consulta Primeros pasos)

El par no tiene claves públicas

Quizás no ha completado la incorporación. Después de que se registren, carga public_key, signing_public_key, identity_public_key_signature y public_key_version desde API reference → Encryption keys.

Descifrado y firmas

El descifrado falla

  • Clave de conversación en bruto desactualizada o incorrecta, o versión de clave incorrecta
  • Cadena encoded_event incompleta
  • El tipo de evento no es un mensaje cifrado que puedas tratar como contenido descifrable

La firma no verifica

La verificación es fail-closed por defecto (reject_unverified = true): el SDK ya rechaza los eventos firmados no verificados, así que un fallo aquí significa que las entradas de verificación son incorrectas, no que debas activar la comprobación. Causas comunes:
  • Entrada de clave de firma faltante o incompleta para el remitente (todos los campos que requiere el Chat XDK—consulta la referencia del Chat XDK)
  • No se pasaron claves de firma en la llamada y ninguna está almacenada mediante set_signing_keys
  • El remitente rotó versiones—vuelve a obtener sus claves públicas
  • Una versión de clave por debajo del piso aceptado nunca verifica
  • En un evento de cambio de clave de grupo, quien lo firmó ya abandonó el grupo, así que sus claves ya no se sirven — consulta Cambios de clave de miembros que se fueron
El setter set_reject_unverified existe para optar por salir de este predeterminado (false, no recomendado). Si lo desactivaste antes, restaura el predeterminado fail-closed:

Una respuesta lleva reply_preview_validation: "Invalid"

Las respuestas descifradas pueden llevar reply_preview_validation ("Valid" / "Invalid"; JavaScript usa 'valid' / 'invalid'). Invalid significa que la vista previa citada dentro del mensaje no coincide con el evento original firmado que incrusta—trata la cita como no confiable y renderiza el contenido citado solo desde el original validado. El mensaje en sí se verifica por separado y sigue siendo auténtico; no se lanza ninguna excepción por una vista previa inválida.

Los eventos antiguos fallan la verificación de forma permanente

Errores como signature missing or no matching signing key o un desajuste ECDSA en eventos antiguos son permanentes. Las firmas son inmutables y se verifican reconstruyendo el payload firmado desde el evento en sí, así que un evento firmado sobre bytes distintos (o nunca firmado) fallará en cada carga futura—ninguna reintentación, actualización de claves o llamada a la API puede sanarlo. Trata estos eventos como tombstones, no como errores reintentables. Rotar la clave de conversación inicia un historial limpio y verificable desde ese punto en adelante; los mensajes nuevos no se ven afectados.

Construcción del payload de envío

Estos errores son específicos del cifrado de X Chat (no errores HTTP generales):

La API devuelve 400 en una llamada que cambia estado

Cada llamada de chat que cambia estado—agregar o rotar claves de conversación, crear un grupo, agregar miembros—requiere action_signatures en el cuerpo de la solicitud, validado en el límite de la API. Una entrada faltante o mal formada (cada una necesita message_id, encoded_message_event_detail y un message_event_signature con signature, public_key_version y signature_version) devuelve inmediatamente una respuesta HTTP 400 problem-details. Usa los métodos prepare del SDK (prepare_conversation_key_change, prepare_group_create, prepare_group_members_change) y envía todas las firmas devueltas—crear un grupo y añadir miembros devuelven dos.

Cifrar y descifrar multimedia

  • Usa la misma clave de conversación (y versión) que el mensaje que referencia el adjunto
  • Trata las respuestas de descarga como texto cifrado hasta que ejecutes decrypt_stream
  • Infiere el tipo MIME después de descifrar; el Content-Type de la descarga a menudo no es el tipo real de imagen
Detalles: Multimedia.

Depuración segura

Al investigar fallos criptográficos:
  • Registra solo los ids de conversación, ids de evento y versiones de clave
  • No registres texto plano, códigos de acceso, claves privadas ni blobs de clave completos
  • Confirma que la versión de clave de firma pasada a set_identity coincide con el public_key_version de tu registro de clave pública
  • Para historial incompleto, pagina todas las páginas de eventos para no saltarte metadatos de cambio de clave antes de descifrar