2 · Datos y ERP·4 min de lectura
Las mil imágenes que no se podían leer
Mil imágenes archivadas. Ninguna abría.
Una operación documentaba su día en foto —entregas, tickets, formatos— por WhatsApp, y un sistema de captura las guardaba. El día que se quisieron leer, ni una sola era una imagen.
El diagnóstico tomó un minuto#
Miramos los primeros bytes de los archivos. Una imagen JPEG empieza con FF D8 FF; un PDF, con %PDF. Estos no empezaban con nada de eso.
WhatsApp cifra su contenido de punta a punta y sirve los archivos con extensión .enc. El capturador había descargado y guardado el archivo cifrado, no la imagen. Mil sobres perfectamente archivados y perfectamente inútiles.
La llave venía en el mismo mensaje#
No estaba perdida: WhatsApp manda el mediaKey en los metadatos, junto al archivo. Con eso se descifra.
Dos caminos, en orden: pedirle el archivo ya descifrado a la API de Evolution, y si esa ya purgó el mensaje, bajarlo del CDN y descifrarlo con mediaKey y AES-CBC.
Se recuperaron 662 archivos, ~81 MB, cero corruptos. Se perdieron 33: las URLs del CDN de WhatsApp caducan a los ~20 días y esas ya habían vencido.
Dos trampas que costaron caro#
El descifrado silenciosamente malo. En la primera pasada, 60 de 64 PDFs salieron ilegibles. WhatsApp deriva la llave con una etiqueta HKDF distinta por tipo de archivo — WhatsApp Image Keys, Document Keys, Video Keys. Usar la equivocada produce un archivo del tamaño correcto y con basura adentro. Si cuentas bytes, parece éxito.
Y el payload venía truncado. El nodo que guardaba los mensajes cortaba en 5,000 caracteres. El mediaKey viaja al final, después de la miniatura: 187 filas quedaron sin llave, y sin llave la foto es irrecuperable en cuanto caduca la URL.
Qué hicimos#
Un script de rescate idempotente y reanudable, que anota lo recuperado y se puede volver a correr sin duplicar. Y un segundo script que audita leyendo los primeros bytes de cada archivo y valida la firma antes de darlo por bueno.
El nodo de captura dejó de truncar: ahora descarta los campos pesados —la miniatura, los sidecars— y conserva íntegro el resto. Probado contra 400 mensajes reales: mediaKey preservado en 251 de 251.
Lo que nos llevamos#
"Guardado" no es "legible". El nombre y la extensión mienten sin esfuerzo; la firma del archivo, no. Y cuando un proceso descifra, contar bytes no sirve de verificación: hay que abrir uno y mirar sus primeros bytes. Uno basta para saber si los otros mil valen algo.