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
- Python
- TypeScript
- Rust
- Go
- C#
- Java
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 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 anulación 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 “¿es la clave de este dispositivo una de las claves registradas en 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 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_keysdel Chat XDK devuelve solo la clave en bruto, sin ese prefijo
- Python
- TypeScript
- Rust
- Go
- C#
- Java
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 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 última clave verificada de cada conversación para que las llamadas posterioresdecrypt_eventyencrypt_*puedan omitirla - 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, cargapublic_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_eventincompleta - 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
set_reject_unverified existe para desactivar este comportamiento 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; nada se lanza por una vista previa inválida.
Los eventos antiguos fallan permanentemente la verificación
Errores comosignature 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—requiereaction_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-Typede descarga a menudo no es el tipo real de la imagen
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_identitycoincide con elpublic_key_versionde 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