Skip to main content
Esta página cubre problemas que son 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 de envío cifrados. 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

Falla el unlock (código de acceso inválido)

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

Cifrar o descifrar falla porque las claves o la identidad no están configuradas

Carga primero las claves privadas, luego configura la identidad de sesión—tu user id 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 anulación 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 “¿es la clave de este dispositivo una de las claves registradas en 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 ambos usan codificaciones distintas:
  • La API almacena y devuelve la clave exactamente como el registro la subió: la codificación DER (SPKI) — la clave en bruto detrás de un prefijo fijo de identificador de algoritmo
  • El get_public_keys del Chat XDK devuelve solo la clave en bruto, sin ese prefijo
Misma clave, dos representaciones. Para comparar, decodifica ambas en base64 y verifica que los bytes de la API terminen con los bytes del SDK (los bytes idénticos también coinciden, en caso de que ambos lados lleguen a tener la misma codificación):
Una vez que coincidan, adopta el public_key_version de esa fila para set_identity. Al comparar versiones (por ejemplo, para elegir la clave más nueva), compara numéricamente—las versiones son marcas de tiempo en milisegundos con longitud de cadena variable, por lo que la 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 última clave verificada de cada conversación para que las llamadas posteriores decrypt_event y encrypt_* puedan omitirla
  2. Confirma que se añadieron claves de conversación para esa versión y que sigues siendo participante (consulta Primeros pasos)

El par no tiene claves públicas

Es posible que no haya terminado el onboarding. Después de que se registre, carga public_key, signing_public_key, identity_public_key_signature y public_key_version desde API reference → Encryption keys.

Descifrado y firmas

Falla el descifrado

  • Clave de conversación en bruto obsoleta 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 se verifica

La verificación es fail-closed por defecto (reject_unverified = true): el SDK ya rechaza eventos firmados no verificados, así que un fallo aquí significa que las entradas de verificación son incorrectas, no que necesites activar la comprobación. Causas comunes:
  • Entrada de clave de firma faltante o incompleta para el remitente (todos los campos requeridos por el Chat XDK—consulta la referencia del Chat XDK)
  • No se pasaron claves de firma en la llamada y no hay ninguna almacenada mediante set_signing_keys
  • El remitente rotó versiones—vuelve a obtener sus claves públicas
  • Una versión de clave por debajo del mínimo aceptado nunca se verifica
  • En un evento de cambio de clave de grupo, el firmante ha abandonado el grupo desde entonces, por lo que sus claves ya no se sirven—consulta Cambios de clave por parte de miembros que han abandonado el grupo
El setter set_reject_unverified existe para desactivar este comportamiento 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; nada se lanza por una vista previa inválida.

Los eventos antiguos fallan permanentemente la verificación

Errores como signature missing or no matching signing key o una discrepancia ECDSA en eventos antiguos son permanentes. Las firmas son inmutables y se verifican reconstruyendo el payload firmado a partir del propio evento, así que un evento que fue firmado sobre bytes diferentes (o nunca firmado) fallará en cada carga futura—ningún reintento, refresco de claves ni 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 a partir de ese punto hacia adelante; los nuevos mensajes no se ven afectados.

Construyendo el payload de envío

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

La API devuelve 400 para una llamada que cambia el estado

Cada llamada de chat que cambia el estado—añadir o rotar claves de conversación, crear un grupo, añadir miembros—requiere action_signatures en el cuerpo de la solicitud, validadas en el límite de la API. Una entrada faltante o mal formada (cada una necesita message_id, encoded_message_event_detail y una message_event_signature con signature, public_key_version y signature_version) devuelve una respuesta problem-details HTTP 400 de inmediato. 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—group create y member adds devuelven dos.

Cifrado y descifrado de multimedia

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

Depuración segura

Al investigar fallos de criptografía:
  • Registra en logs los IDs de conversación, los IDs de evento y las versiones de claves únicamente
  • No registres en logs texto plano, códigos de acceso, claves privadas ni blobs de clave completos
  • Confirma que la versión de la clave de firma pasada a set_identity coincide con el public_key_version de tu registro de public-key
  • Para historial incompleto, pagina todas las páginas de eventos para no saltar los metadatos de key-change antes de descifrar