Después de que el cliente cifra y sube el espacio de trabajo, por qué no puedes abrir ese texto cifrado local

El 18 de septiembre de 2026, el desarrollador ferstar limpiaba el disco y encontró esto: con la sesión iniciada, un cliente de programación con IA empaquetaba el espacio de trabajo entero, lo cifraba e intentaba subirlo directo al almacenamiento de objetos. El paquete era texto cifrado, pero la clave pública RSA que envolvía la clave de contenido la entregaba el servidor en ese momento. La clave privada nunca llegaba a este ordenador. De ahí la frase que choca: esos cientos de megabytes «ya cifrados» no los abres tú, y el cliente tampoco. El 21 de septiembre el fabricante anunció el código abierto y retiró la ruta de subida. Las cuatro palabras «cifrar y subir» no se convirtieron por eso en conocimiento cero.

Empieza por la conclusión: «ya cifrado» solo dice que los bytes empaquetados no son el espacio de trabajo en claro. No dice que tú tengas la clave de descifrado, ni que la nube no pueda leer el contenido. En el cifrado de sobre, una clave simétrica se envuelve con una clave pública que acaba de entregar el servidor, y la privada se queda en la nube. El diseño quiere que la nube pueda abrirlo. En este equipo puedes contrastar tres cosas: si tú abres este texto cifrado, si Network muestra el espacio de trabajo en claro, y si sigue apareciendo un paquete nuevo pendiente de enviar después de apagar los interruptores. No confundas «AES se ejecutó en local» con «solo yo puedo descifrar».

La intención de búsqueda, en una frase

El cifrado del camino y «tú tienes la clave» no son la misma capa. Un cliente puede ejecutar AES en este equipo, convertir el espacio de trabajo en texto cifrado y enviar ese texto cifrado al almacenamiento de objetos. Si la clave pública que envuelve la clave de contenido viene del servidor, y la privada nunca entró en este ordenador, el archivo no es una copia que puedas restaurar. Es un sobre que solo abre la nube. Quien escucha el camino no ve el texto en claro. El servidor que guarda la clave privada, sí.

Esta nota es para quien acaba de leer que un cliente «cifra el espacio de trabajo antes de subirlo» y quiere separar «hay texto cifrado en el disco» de conocimiento cero. También es para quien tiene que pasar un repositorio o una clave a un compañero sin entregar el derecho de descifrado a un proveedor. No sustituye el aviso del fabricante ni es una guía para desinstalar un editor. Qué conviene llevarse: quién guarda la clave en un cifrado de sobre, qué alcance ya escribía el listado en claro, qué no demuestra «destruir de inmediato», y cómo comprobar en este equipo si tú puedes abrir el archivo.

Qué dejó fijado el desmontaje

El 18 de septiembre de 2026, ferstar publicó la investigación. No empezó como un concurso de captura de paquetes. Empezó como limpieza de disco. En local, ~/.zcode ocupaba más de 700 MB. Bajo v2/checkpoints/ había un .enc de unos 313 MB. El archivo de estado de al lado decía que el espacio de trabajo rondaba los 345 MB, que kind era baseline y que failureCount era 564. El repositorio en sí pesaba unos 10 GB. Tras dejar fuera las dependencias, los 345 MB restantes eran casi solo archivos centrales del proyecto.

Reconstruyó la subida en dos pasos. Primero, el cliente llamaba a POST /api/v1/snapshot/upload-credential en zcode.z.ai. El servidor devolvía un identificador de instantánea, una firma de formulario para el almacenamiento de objetos, un tope de tamaño y una clave pública RSA de esa ronda. Segundo, la máquina armaba un tar.gz, lo cifraba con una clave simétrica de un solo uso bajo AES-256-CTR, envolvía esa clave con RSA-OAEP-SHA256 y hacía un POST de formulario de tar.gz.enc directo al OSS de Alibaba Cloud. Un callback del almacenamiento registraba el objeto en el backend del proveedor. El servidor de aplicación no tocaba el archivo cifrado. El registro y la clave privada seguían en la nube.

El alcance no era el árbol de trabajo actual. Un listado local en claro enumeraba 42.411 archivos: .git/lfs/ unos 196,1 MB (56,8 %), .git/objects/ unos 102,2 MB (29,6 %), .git/logs/ unos 0,6 MB, y código más documentación unos 46,2 MB (13,4 %). .git era el 86,6 % del paquete. Una subida correcta habría entregado a la nube el historial de commits, secretos ya borrados del árbol pero aún vivos en el almacén de objetos, nombres de ramas que nunca se empujaron y hosts de intranet en .git/config. Un segundo listado, entre espacios de trabajo, hacía un hash de la configuración global y se lo llevaba también.

A las 17:44 del 18 de septiembre el fabricante escribió en su comunidad de usuarios. Dijo que la subida venía de un índice del repositorio de código, activado por defecto, usado para puntos de control de sesión, vuelta atrás de versiones y el Repo Wiki, y que los datos se destruían en cuanto se generaba el Wiki. El 21 de septiembre, National Business Daily informó de que ZCode abriría el código del cliente; la Academia China de Tecnología de la Información y las Comunicaciones (CAICT) dijo que el cubo zcode-prod no tenía datos; NSFOCUS dijo que el cubo y los objetos se habían borrado; y el cliente v3.14.0 había retirado la generación de instantáneas y la ruta de subida. ferstar añadió un resultado partido: el proyecto comercial de 313 MB superaba el tope, reintentó 564 veces y no salió de la red local. Otro espacio de trabajo, un repositorio público de 538 archivos, comprimido y cifrado pesaba unos 15 KB, y el estado era «aceptado por el servidor». Así que «¿salió algo de esta máquina?»: al menos esa copia pequeña, sí.

Por qué el cifrado de sobre no es un archivo que tú abres

AES-256-CTR más RSA-OAEP es el sobre de manual. El contenido se cifra con una clave simétrica de vida corta. Esa clave se envuelve después con una clave pública. Los nombres de algoritmo suenan duros. Quién puede leer el archivo depende de dónde salió la pública y dónde se sienta la privada. El relato es explícito: la pública se entregaba al pedir la credencial de subida, la privada correspondiente nunca entró en este ordenador, y desenvolver el sobre con claves privadas que ya estaban en la máquina falló. El propio cliente no podía abrir el texto cifrado del disco.

Eso es lo contrario de una copia que puedas restaurar. Time Machine, los objetos Git locales y un archivo que cifras con una contraseña y luego copias a otro sitio guardan el material de descifrado de tu lado: una contraseña, una clave local o un llavero que tú abres. Cuando solo el servidor tiene la clave privada, el objetivo de diseño cambia. Un tercero en el camino no debería ver los bytes. Al llegar, la nube debería poder abrirlos. La frase del propio ferstar fija el uso: una llave que solo puede usar el servidor sirve para que el servidor lea tu código. No sirve para que tú hagas una vuelta atrás.

He Yuan, del Centro de Investigación de Derecho de Datos de la Universidad Jiao Tong de Shanghái, dijo a National Business Daily algo más estrecho. El cifrado es una medida de seguridad. No es anonimización, y no sustituye el aviso ni la minimización. Si el proveedor sigue pudiendo descifrar, los datos cifrados aún se pueden recuperar y tratar. «Borrar en cuanto se usa» solo baja la retención a largo plazo. No responde si la primera recogida era necesaria. Juntas las dos frases: la fuerza del algoritmo no demuestra quién tiene la clave, y una declaración de destrucción no demuestra el alcance de la recogida.

No uses un repositorio de producción, una clave cloud viva ni código de un cliente para «reproducir la subida». Contrasta si en este equipo ya hay texto cifrado pendiente de enviar, qué ruta y qué recuento de fallos anota el archivo de estado, y si tú puedes abrir el archivo. Volver a enviar el repositorio vivo no devuelve la clave privada a tus manos.

El listado en claro ya escribe el alcance

No puedes abrir el texto cifrado. Eso no convierte el alcance en una suposición. El listado de archivos escrito al empaquetar se quedó en el disco, y estaba en claro. Esas 42.411 filas separan «el árbol de código actual» de «la vida del repositorio». El árbol actual era cerca del 13,4 %. El resto era la caché LFS, el almacén de objetos completo y el reflog. Una API Key que ya borraste del árbol de trabajo puede seguir en .git/objects si alguna vez se confirmó en un commit. El nombre de una rama no empujada puede delatar una función que aún no es pública. Un hostname Git de intranet vive en .git/config. No hace falta abrir el texto cifrado para ver, desde el lado del listado, que entró en el paquete.

Dos interruptores de la pantalla parecen un interruptor general. En el código no lo eran. Tras alinearlos con el relato, «mejorar la experiencia» solo controlaba si los datos podían usarse para entrenar el modelo, y el «índice de instantáneas del repositorio» solo controlaba si la nube construía un índice. El empaquetado y la subida directa seguían mientras el JWT de sesión era válido. Los puntos de captura estaban antes de cada prompt, y en repo-wiki-update al terminar una tarea. En una sesión activa se registraron hasta 62 capturas. Unos treinta minutos después de borrar a mano el paquete pendiente, apareció un archivo nuevo de 313 MB, y el contador de fallos pasó de 564 a 565. Borrar el archivo no es apagar el interruptor.

La política de privacidad archivada el 18 de septiembre seguía diciendo que su última actualización era el 2026-06-15. El alcance de recogida que describía era texto, archivos y código enviados en una conversación. No decía «tras iniciar sesión, empaquetar automáticamente el espacio de trabajo completo y el historial Git». La política sostiene una afirmación: el proveedor dijo que recogía lo que envías en una sesión. No sostiene otra: que una instantánea completa ya estuviera escrita en la página que aceptaste. Los interruptores y la política hay que contrastarlos con el artefacto. ¿Hay un .enc nuevo en local? ¿workspacePath en el archivo de estado apunta al proyecto comercial que estás escribiendo?

Qué demuestran «cifrado» y «destruido de inmediato»

Parte las frases de la noticia en «esto sostiene» y «esto no sostiene». Es más estable que seguir los adjetivos. Texto cifrado en el disco solo sostiene esto: los bytes empaquetados no son un árbol de directorios en claro. Destruir de inmediato solo sostiene esto: el proveedor dice que no conserva ese objeto mucho tiempo después de generar el Wiki. Buscar en el árbol de código abierto y no encontrar /api/v1/snapshot/upload-credential solo sostiene esto: la ruta ya no está en el árbol que es público ahora. Un cubo evaluado como vacío solo sostiene esto: ese cubo estaba vacío en el momento de la evaluación.

Ninguna de esas frases cubre el otro lado. El texto cifrado no sostiene «tú puedes restaurar el espacio de trabajo». Destruir de inmediato no sostiene «nadie tenía la clave privada antes del borrado», ni «el alcance de la recogida coincidía con la opción que marcaste». Un árbol de código abierto aplanado en dos commits no sirve para comparar cómo estaba escrito el sidecar antiguo. Un cubo vaciado después no se rebobina para mostrar quién descifró o copió objetos ya aceptados antes del 18 de septiembre. ferstar anotó la tensión: si la vuelta atrás de un punto de control de verdad necesitaba una subida completa a la nube, eso choca en el tiempo con «destruir en cuanto se genera». La implementación de puntos de control en el árbol abierto es un diff Git local. Los metadatos son JSON bajo ~/.zcode/checkpoints/. No dependen de esa ruta de subida.

Lo que ves Qué sostiene Qué no sostiene
En el disco hay un .enc y el algoritmo dice AES-256 Los bytes empaquetados no son el espacio de trabajo en claro Solo tú puedes descifrar, y la nube no lee el contenido
La clave pública RSA la entrega el servidor al pedir la credencial La clave privada que abre el sobre no está en este ordenador Esto es una copia para restaurar entre dispositivos
Apagas «mejorar la experiencia» y el «índice del repositorio» Puede haberse parado el permiso de entrenamiento o el índice en la nube El empaquetado y la subida directa se pararon con ellos
El proveedor dice que destruye el objeto al generar el Wiki Declara que no retiene ese objeto a largo plazo El primer empaquetado coincidía con el interruptor que marcaste
Una evaluación dice que el cubo no tiene datos Ese cubo estaba vacío en el momento de la evaluación Los objetos aceptados antes nunca se descifraron ni se copiaron
El archivo de 313 MB falló 564 veces Esa instantánea del proyecto comercial no salió Ningún espacio de trabajo salió de la máquina de ningún usuario

Qué capas puedes contrastar ahora

Un eslogan no es una prueba. Abajo solo se contrastan tres capas que controlas tú: si en este equipo hay un artefacto pendiente de enviar, si la petición se llevó el espacio de trabajo en claro, y si tú puedes abrir este texto cifrado. No vuelvas a meter un «envío de prueba» en un repositorio de producción.

  1. Mira primero el directorio de datos local, no la página de producto. En la carpeta de puntos de control o de caché de un cliente de programación con IA, un .enc de cientos de megabytes y un archivo de estado con workspacePath, encryptedSizeBytes y failureCount dicen que el empaquetado ya ocurrió. Una ruta que coincide con el proyecto que estás escribiendo pesa más que «solo enviamos el contexto de la conversación».
  2. Abre las herramientas para desarrolladores o un observador de red del sistema y marca Preserve log. Mira solo la línea de petición y el host: ¿hay una interfaz que pide la credencial de subida? ¿hay un POST de formulario directo al almacenamiento de objetos? Lo que contrastas es «si el texto cifrado salió de esta máquina», no volver a enviar el repositorio. Si en el cuerpo aparecen código fuente, una contraseña o un .pem en claro, esta capa ya falló.
  3. Haz una pregunta que se puede ejecutar: este texto cifrado local, ¿lo abro yo con mi contraseña o con una clave privada de este equipo? Si no se abre, y el proveedor también dice que el cliente no lo abre, la clave no está de tu lado. Si se abre, entonces sí puedes hablar de «esto es una copia para mí».
  4. Apaga todos los interruptores cuyo nombre suene a «privacidad / índice / optimizar», espera un ciclo de sesión y vuelve a mirar si el directorio de puntos de control tiene un paquete nuevo pendiente y si el contador de fallos sigue subiendo. El texto del interruptor no demuestra un corte general. Un archivo nuevo, sí.
  5. Cuando necesites un archivo que tú mismo puedas abrir, cambia a un canal cuya frontera de cálculo esté escrita. Abre la caja de cifrado, elige un archivo canario que puedas tirar y ponle de nombre canary-fp-20260922-vendor-key.txt. La contraseña se queda en este equipo. Abre Network, marca Preserve log y pulsa cifrar. En la línea de petición y en el cuerpo no deberían aparecer el contenido del archivo, la contraseña ni el nombre completo como dato de negocio. La salida es .lock o .enc, y un archivo no pasa de 5 GB. Con la misma contraseña, descifra en este equipo: el canario debe volver. Lo abres porque la contraseña está en tus manos, no porque el nombre del algoritmo lleve AES.

El quinto paso no pide que la caja de cifrado sustituya al cliente de programación. Solo ofrece un contraste: también es «cifrado en local», pero la derivación de la clave y AES-256-GCM se quedan en esta pestaña, y el archivo y la contraseña no se suben por defecto como dato de negocio. El texto cifrado te lo llevas, y lo abres. La nota anterior sobre el router era otra capa: HTTPS solo protege hasta ese salto. La capa de más en esta nota es quién abre el sobre después de que el texto cifrado se va.

La contraseña completa y el texto cifrado no deben ir por el mismo chat. El .lock de la caja de cifrado se puede copiar a un disco en la nube; la contraseña debe ir por un canal que ya hayas verificado, o una contraseña corta puede ir detrás de # en un enlace Burn-Link. Si pegas la llave y el candado en el mismo mensaje, el sobre ya no existe para quien ve ese mensaje.

Tres lecturas que se pasan de «cifrado local»

La primera: leer «se llamó a AES en este equipo» como «solo yo puedo descifrar». Que la llamada ocurra en local solo dice que el texto en claro seguía en este ordenador al empaquetar. Si la pública viene del servidor y la privada no aterriza aquí, el derecho de descifrado está en la nube. La lista de algoritmos, la longitud de la clave, CTR o GCM, no responden «en qué proceso vive la clave privada».

La segunda: leer «subida directa al almacenamiento de objetos, sin pasar por el servidor de aplicación» como «el proveedor no lo ve». El archivo puede no pasar por el servidor de la aplicación, y aun así el callback de registro y la clave privada siguen del lado del proveedor. Saltarse la sala de máquinas de la aplicación reduce una copia en claro en los registros de la app. No reduce el derecho de descifrado. La nota del router decía que HTTPS no frena a un proxy de la capa de aplicación. Aquí lo que no se frena es «el extremo que tiene la clave privada».

La tercera: leer «destruido de inmediato / código abierto / el cubo está vacío» como «nunca se recogió». Destruir baja la retención. El código abierto te deja contrastar el árbol actual. Un cubo vacío dice que en la evaluación no había objetos. Ninguno de los tres equivale, por sí solo, a que los objetos históricos no se hayan abierto, ni a que el interruptor de entonces cubriera todo el Git. Lo que cabe en una nota de entrega es si este equipo sigue generando paquetes pendientes de enviar, y si tú puedes abrir el texto cifrado que vas a sacar. No el «ya corregido» del titular.

Preguntas frecuentes

Si en el disco ya hay texto cifrado, ¿eso es conocimiento cero en este equipo?

No. El texto cifrado solo dice que los bytes empaquetados no son el espacio de trabajo en claro. Si la clave pública RSA que envuelve la clave de contenido la entrega el servidor en ese momento, la clave privada nunca aterriza aquí. Ni tú ni el cliente abrís el archivo. Es un sobre para que lo lea la nube, no una copia que puedas restaurar tú.

Si dicen que lo destruyen en cuanto se sube, ¿qué más se puede contrastar?

«Destruir de inmediato» baja la retención a largo plazo. No responde si el primer empaquetado superó el interruptor que marcaste, ni quién tenía la clave privada antes de borrar. Vaciar el cubo después no permite rebobinar quién descifró o copió objetos ya aceptados antes del 18 de septiembre.

Si apago «mejorar la experiencia» y el «índice del repositorio», ¿se para también la subida?

En el cliente antiguo que se desmontó, esas dos opciones cubren si los datos pueden usarse para entrenar y si la nube construye un índice. No cortan el empaquetado ni la subida directa. Hay que mirar si existe un interruptor aparte de «dejar de generar instantáneas», y si al apagarlo sigue apareciendo texto cifrado nuevo pendiente de enviar.

Si quiero entregar un archivo que yo mismo pueda abrir, ¿qué canal uso?

Cifra primero en esta pestaña con AES-256-GCM y da la contraseña solo a quien ya hayas verificado. Abre la caja de cifrado: un archivo no pasa de 5 GB, la salida es .lock o .enc, el archivo y la contraseña no se suben por defecto, y está listo para usar, sin cuenta. Un secreto corto va por Burn-Link, con la clave detrás de #, en la forma s.html?id={id}#{key}. Si en el ticket o en el registro aún hay teléfono o número de documento, ocúltalos antes en limpiar enlaces: el texto original no se sube como dato de negocio.

Si tienes que poder abrirlo tú, usa un canal listo para usar

Si quieres practicar en una página que deja escrita la frontera de cálculo —«yo abro el texto cifrado y la contraseña no entra en Network»—, abre la caja de cifrado de FastPwd. No hace falta registrarse. Elige el canario de arriba, haz AES-256-GCM en esta pestaña y contrasta como en la sección anterior: en la petición no deberían aparecer el contenido ni la contraseña, y la misma contraseña debe restaurar el archivo en este equipo. La salida .lock o .enc se puede copiar a un disco en la nube. La contraseña no va en el mismo chat, ni en ningún cuadro de una IA.

Si además vas a pegar un trozo del repositorio en un modelo en la nube, da por hecho que el extremo receptor ve el texto completo que pegas. Un router deja el paquete de llamada en claro donde termina HTTPS; eso ya está en la nota anterior. Esta nota añade una pregunta: si el cliente primero «cifra» y luego sube, ¿la clave privada que abre el sobre está de tu lado? Si fallan las dos capas, no dejes claves cloud vivas, claves privadas SSH ni datos de clientes dentro de un espacio de trabajo que luego entrega a una herramienta que empaqueta. Ocultar por reglas solo tapa campos habituales. Una clave entera va por Burn-Link, o no sale.

La próxima vez que leas «ciframos en local y luego subimos», recuerda tres cosas. Primera: pregunta quién tiene la clave privada o la contraseña, no solo el nombre del algoritmo. Segunda: pregunta si el listado llega al historial .git que no son los archivos actuales. Tercera: contrasta con un texto cifrado que tú mismo puedas abrir, no con una declaración de destrucción. En una nota de entrega caben esas tres frases. No cabe «en el disco hay texto cifrado, así que la nube no lo ve».

Para seguir leyendo

Poner contraseña a un ZIP antes de subirlo a la nube no tapa los nombres, y no es AES-GCM en este equipo: Qué bloquea una contraseña ZIP antes de subir a la nube, y por qué no es AES-GCM local. HTTPS solo cifra hasta el salto del router, y no frena una clave SSH dentro del prompt: Por qué aparecen claves SSH en un volcado de 6 TB de un router LLM, y qué capa no puede detener HTTPS. Cómo contrastar tú mismo, en Network, que el «cifrado local» de una página no envió el original: Cómo comprobar que el cifrado local del navegador no envió el original.