Pieza 5 de 64
Otra épocaPieza nº 0005 de 64

Ocho cifras para un cifrado de 1977

Quien entra en el registro electrónico de Red.es con su certificado carga, antes de nada, un fichero de 166.701 bytes. Dentro hay un programa completo de cifrado DES, el algoritmo que Estados Unidos aprobó en 1977 y retiró en 2005, y una clave para usarlo que es un número de ocho cifras.

Dominio
sede.red.gob.es
Guardado
31 AGO 2026
Comprobado en vivo
15 SEP 2026
Citas
10 en 2 ficheros guardados
Lectura
unos 4 min
Captura de https://sede.red.gob.es/
foto 1La portada de sede.red.gob.es el 26 de septiembre de 2026: la sede electrónica de Red.es, con sus convocatorias, licitaciones y trámites.Captura del 26 de septiembre de 2026, 16:50 (hora peninsular)

La página es la de acceso al registro electrónico: un recuadro titulado «Autenticación», un texto que avisa de que hará falta un certificado electrónico o el DNI electrónico, y dos botones. Antes de todo eso, el HTML carga tres ficheros de programa, y el primero viene del propio dominio. El servidor dice que ese fichero no se toca desde el 18 de mayo de 2022. Lo capturamos el 31 de agosto de 2026 y lo volvimos a pedir el 15 de septiembre. Los mismos 166.701 bytes, la misma huella.

Captura de https://sede.red.gob.es/eRegistro/inicio!seleccion.action?expedienteSeleccionado=QS-001
foto 2La página de acceso al registro electrónico de la sede de Red.es el 16 de septiembre de 2026, tal como carga: no se pulsó ningún botón. Recuadrado, el aviso que pide certificado electrónico o DNI electrónico. Cuando aparece ese recuadro, el cliente de firma —⁠con el DES dentro⁠— ya está cargado. Arriba a la derecha, la hora del servidor.Captura del 16 de septiembre de 2026, 01:02 (hora peninsular) · el recuadro es nuestro
1de 10sede.red.gob.es/eRegistro/accesoFirma/autenticacionAppletFirma.actionlínea 311 de 525
Copia
archivo
Guardado
31 ago 2026
Peso
22,6 kB
sha256
b7ba4731e98c…
309<body>
310    
311        <script type="text/javascript" src="https://sede.red.gob.es/afirma/js/autoscript.js"></script>
312        <script type="text/javascript" src="/eRegistro/js/autoscript/funcionesFirma_messages.js"></script>
313        <script type="text/javascript" src="/eRegistro/js/autoscript/funcionesFirma.js"></script>
1Lo primero del cuerpo de la página de autenticación: el cliente de firma y sus dos ficheros de apoyo. Captura del 31 de agosto de 2026.

Lo primero que hace el cliente al arrancar es decidir cómo va a hablar con AutoFirma. Tiene tres caminos: una conexión local con el programa, un puerto del propio ordenador, o un servidor intermedio al que la página sube los datos y del que la aplicación los descarga. El tercero es el que se lleva esta pieza. La condición que lo elige está escrita en la primera línea del reparto: si se ha forzado ese modo, o si el sistema es iOS, o si es Android. El teléfono, vamos.

2de 10sede.red.gob.es/afirma/js/autoscript.jslínea 564 de 4.207
Copia
archivo
Guardado
31 ago 2026
Peso
166,7 kB
sha256
e1774d2f3ef4…
562// Si se fuerza el uso de servidor intermedio o estamos en un dispositivo movil,
563// usamos servidor intermedio
564if (forceWSMode || Platform.isIOS() || Platform.isAndroid()) {
565    clienteFirma = new AppAfirmaJSWebService(clientAddress, window, undefined);
566}
567// Si podemos utilizar un WebSocket local y no estamos en Internet Explorer
2El reparto de caminos, con su comentario. Debajo vienen los otros dos: una conexión local con el programa si el navegador lo admite y no es Internet Explorer, y un puerto del propio ordenador.

Por ese camino los datos del trámite pasan por un servidor, así que el cliente los cifra antes de soltarlos. Para eso necesita una clave, y la función que la fabrica se llama generateCipherKey. Pide un número aleatorio al navegador, se queda con el resto de dividirlo entre cien millones y lo rellena con ceros a la izquierda hasta ocho dígitos. La clave es un número entre 00000000 y 99999999, escrito como ocho caracteres de texto. Son cien millones de claves posibles, pocas más que matrículas españolas, que son ochenta millones.

3de 10sede.red.gob.es/afirma/js/autoscript.jslínea 3089 de 4.207
Copia
archivo
Guardado
31 ago 2026
Peso
166,7 kB
sha256
e1774d2f3ef4…
3086if (typeof window.crypto != "undefined" && typeof window.crypto.getRandomValues != "undefined") {
3087    var randomInts = new Uint32Array(1);
3088    window.crypto.getRandomValues(randomInts);
3089    random = zeroFill(randomInts[0] % 100000000, 8);
3090}
3091else {
3092    random = zeroFill(Math.floor(((rnd() * MAX_NUMBER) + 1) % 100000000), 8);
3La fábrica de claves entera. Arriba, el camino que usa el generador de números aleatorios del navegador; abajo, el de respaldo. Los dos terminan en lo mismo: ocho dígitos rellenados con ceros por la izquierda.

Hay un segundo camino, para cuando el navegador no tiene window.crypto, la fuente de números aleatorios que traen todos los navegadores desde 2011. Entonces la clave sale de una función propia que se declara “con una distribución homogénea”: multiplica una semilla por 9301, le suma 49297 y se queda con el resto de dividir entre 233280. Es el generador que circulaba en los manuales de los años ochenta. Para arrancar multiplica los milisegundos del reloj por mil y por otro número aleatorio.

4de 10sede.red.gob.es/afirma/js/autoscript.jslínea 3116 de 4.207
Copia
archivo
Guardado
31 ago 2026
Peso
166,7 kB
sha256
e1774d2f3ef4…
3113    if (seed == undefined) {
3114        seed = new Date().getMilliseconds() * 1000 * Math.random();
3115    }
3116    seed = (seed * 9301 + 49297) % 233280;
3117    return seed / 233280;
3118}
4El generador de respaldo, con su promesa de homogeneidad. Los tres números son los del ejemplo clásico de generador de números al azar que se copiaba de manual en manual.

Con esa clave se cifra la operación entera. El cliente arma un pequeño XML con los parámetros (el formato de firma, el algoritmo, el documento en base 64) y lo manda al servidor de depósito con un envío cuyo cuerpo empieza por «op=put». Esto ocurre cuando la llamada no cabe en una dirección web, y el listón está en 2.000 caracteres. Cualquier documento de verdad lo pasa. El resultado, el certificado del ciudadano y la firma, vuelve por el mismo sitio y se descifra con la misma clave.

5de 10sede.red.gob.es/afirma/js/autoscript.jslínea 3174 de 4.207
Copia
archivo
Guardado
31 ago 2026
Peso
166,7 kB
sha256
e1774d2f3ef4…
3172var requestData =
3173    "op=put&v=1_0&id=" + fileId + "&dat=" +
3174    cipher(buildXML(op, params), cipherKey);
3175
3176try {
3177    httpRequest.send(requestData);
5Lo que se sube al servidor intermedio: un identificador de fichero y, en el campo dat, la operación cifrada con la clave de ocho cifras.

La aplicación instalada tiene que conocer esa clave para descifrar lo que la página depositó. Se la pasa la propia dirección con la que se la llama. El cliente construye una dirección que empieza por «afirma://», o por «intent://» si es Chrome en Android, y le añade un parámetro llamado key con las ocho cifras dentro. Esa dirección es la que el navegador abre para despertar a AutoFirma, y ahí va la clave, escrita.

6de 10sede.red.gob.es/afirma/js/autoscript.jslínea 3271 de 4.207
Copia
archivo
Guardado
31 ago 2026
Peso
166,7 kB
sha256
e1774d2f3ef4…
3268        newParams[j++] = {key:"rtservlet", value:rtServlet};
3269    }
3270    if (cipherKey != null || cipherKey != undefined) {
3271        newParams[j++] = {key:"key", value:cipherKey};
3272    }
3273    return buildUrl(op, newParams);
3274};
6La clave se añade como un parámetro más de la dirección afirma:// que el navegador abre para invocar a la aplicación de firma.

Queda el algoritmo. El comentario que encabeza la función de cifrado lo dice con todas las letras: «Algoritmo DES, modo CBC, sin Padding». Doce líneas más abajo está la llamada de verdad, con la clave, los datos y tres números: un 1, un 0 y un nulo. El 1 quiere decir cifrar. El 0 es el modo. Y del relleno que el comentario niega se encarga el propio código, que cuenta a mano los bytes que faltan para llegar a múltiplo de ocho y antepone esa cuenta al resultado, separada por un punto.

7de 10sede.red.gob.es/afirma/js/autoscript.jslínea 3615 de 4.207
Copia
archivo
Guardado
31 ago 2026
Peso
166,7 kB
sha256
e1774d2f3ef4…
3612}
3613
3614/**
3615 * Realiza un cifrado DES compatible con Java (Algoritmo DES, modo CBC, sin Padding).
3616 * @param dataB64 Cadena de texto base 64.
3617 * @param key Clave de cifrado.
3618 * @return Base 64 cifrado.
7Lo que el comentario promete, escrito por quien programó la función: CBC y sin relleno. Las dos cosas se desmienten en las dos vitrinas siguientes.
8de 10sede.red.gob.es/afirma/js/autoscript.jslínea 3627 de 4.207sigue en el mismo fichero · 12 líneas más abajo
3625    // Los datos cifrados los pasamos a base 64 y, antes de devolverlos le anteponemos el padding que
3626    // le habra agregado el metodo de cifrado separados por un punto ('.').
3627    return padding + "." + Cipher.stringToBase64(Cipher.des(key, data, 1, 0, null)).replace(/\+/g, "-").replace(/\//g, "_");
3628}
3629
3630/**
8Lo que la llamada pide: clave, datos, 1 (cifrar), 0 (modo) y ningún vector inicial. Arriba, el relleno contado a mano que el comentario decía no hacer.

Casi cuatrocientas líneas más abajo, en la librería que hace el trabajo, se ve qué significa ese número. El modo 1 es CBC: cada bloque se mezcla con el anterior antes de cifrarse, y por eso hace falta un vector inicial. El 0 es el otro, ECB: cada bloque de ocho bytes se cifra por su cuenta, sin encadenar nada, de modo que dos bloques iguales del documento dan dos bloques iguales del resultado. El comentario anuncia el primero; la llamada pide el segundo.

9de 10sede.red.gob.es/afirma/js/autoscript.jslínea 4001 de 4.207
Copia
archivo
Guardado
31 ago 2026
Peso
166,7 kB
sha256
e1774d2f3ef4…
3998var result = "";
3999var tempresult = "";
4000
4001if (mode == 1) { //CBC mode
4002    cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
4003    cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
4004    m=0;
9La librería, casi cuatrocientas líneas más abajo, aclara cuál es cuál: el 1 es CBC y necesita el vector inicial que se acaba de ver pasar como nulo.

La misma librería sabe hacer Triple DES, que es DES aplicado tres veces y lo que se usó durante años cuando una pasada se quedó corta. Lo decide sola, mirando la longitud de la clave: con nueve caracteres o más, tres pasadas; con ocho o menos, una. La clave que fabrica esta página tiene ocho caracteres exactos. Le falta uno para que la propia librería, sin que nadie se lo pidiera, hubiera hecho el trabajo tres veces. Una pasada, pues.

10de 10sede.red.gob.es/afirma/js/autoscript.jslínea 4087 de 4.207
Copia
archivo
Guardado
31 ago 2026
Peso
166,7 kB
sha256
e1774d2f3ef4…
Tapado
1 tramos ▒
4084var pc2bytes13 = new Array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105);
4085
4086//how many iterations (1 for des, 3 for triple des)
4087var iterations = key.length > 8 ? 3 : 1; //changed by ▒▒▒▒ 16/6/2007 to use Triple DES for 9+ byte keys
4088//stores the return keys
4089var keys = new Array (32 * iterations);
4090//now define the left shifts which need to be done
10Triple DES, sí, pero solo si la clave pasa de ocho caracteres. La de esta sede mide ocho exactos. El nombre del autor del parche lo tapa el museo.
▒Los tramos ▒ de esta cita no están así en el fichero: los tapa el museo. Se sustituye cada letra y cada cifra por un bloque, sin cambiar la longitud, para no publicar un identificador de sesión ni una dirección de una red interna. Todo lo demás de la cita es literal.

DES es de 1977. Ese año el Gobierno de Estados Unidos lo aprobó como norma federal de cifrado, con clave de 56 bits, y en 2005 lo retiró. La librería que lo implementa aquí lleva en su cabecera la fecha de julio de 2001 y un parche fechado el 16 de junio de 2007. La cabecera entera trae los nombres de sus dos autores y sus páginas personales, y por eso no la reproducimos. Es el código que se pone en marcha cuando alguien intenta firmar un trámite desde el móvil.

El comentario promete CBC. La llamada pide el otro modo. La clave son ocho cifras, y todo esto se pone en marcha cuando alguien saca el móvil para firmar.

Lo que decimos
  • El fichero que sede.red.gob.es servía el 15 de septiembre de 2026 contiene una implementación de DES en JavaScript.
  • La clave que genera para el modo de servidor intermedio es un número de ocho cifras, y viaja como parámetro en la dirección afirma:// con la que se llama a la aplicación de firma.
  • La llamada de cifrado pasa un 0 donde la librería reconoce el 1 como CBC, y pide una sola pasada porque la clave no llega a nueve caracteres.
  • Ese camino se toma cuando el trámite se abre en iOS o en Android, o cuando la página fuerza el modo de servidor intermedio.
Lo que no decimos
  • No decimos que nadie haya leído ni alterado ningún trámite: no lo sabemos y no hemos probado nada contra ese servidor.
  • No decimos que una firma se pueda falsificar; la firma la hace la aplicación instalada, con el certificado del ciudadano, fuera del navegador.
  • No decimos que esto sea cosa de este organismo: el fichero es el cliente estándar de @firma y aparece igual en otros 42 hosts del archivo.
  • No decimos qué versión de ese cliente es la vigente hoy, ni si alguna la ha cambiado.
Procedencia

De dónde sale cada cita

Cada trozo de código de esta ficha está en un fichero guardado tal como lo entregó el servidor, con su huella (sha256) y su hora. Las citas entre «» se comprueban por programa contra ese fichero antes de publicar.

Desgobierno Digital · https://desgobiernodigital.com/piezas/red-des-ocho-cifras/ · copia impresa de la edición generada el 19 de octubre de 2026 · Un proyecto de BQuant · correcciones: @Gsnchez