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
- Python
- TypeScript
- Rust
- Go
- C#
- Java
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 elpublic_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.
- Python
- TypeScript
- Rust
- Go
- C#
- Java
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 elpublic_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_keysdel Chat XDK devuelve la clave en bruto sola, sin ese prefijo
- Python
- TypeScript
- Rust
- Go
- C#
- Java
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 comoMessage 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.
- Descifra el material de clave desde
conversation_key_change_event(eventos en vivo) ometa.conversation_key_events(historial) conextract_conversation_keys, o incluye esos blobs endecrypt_events—conset_cache_keys(true)habilitado,decrypt_eventstambién retiene la clave verificada más reciente de cada conversación para que las llamadas posteriores adecrypt_eventyencrypt_*puedan omitirla - 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, cargapublic_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_eventincompleta - 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
set_reject_unverified existe para optar por salir de este predeterminado (false, no recomendado). Si lo desactivaste antes, restaura el predeterminado fail-closed:
- Python
- TypeScript
- Rust
- Go
- C#
- Java
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 comosignature 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—requiereaction_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-Typede la descarga a menudo no es el tipo real de imagen
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_identitycoincide con elpublic_key_versionde 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