Algunos conceptos básicos de cifrado

Máquina de cifrado Hagelin M-209

Nunca insistimos lo suficiente en lo importante que es el cifrado y que es necesario hacerlo bien. En Encryption: Ciphers, Digests, Salt, and IV - What You Need to Know algunas definiciones básicas de la terminología relacionada con el tema.

El cifrado sería un método para convertir los datos en algo que no puede utlilizarse y que solo puede volverse a hacer útil mediante el descifrado.

Encryption is a method of turning data into an unusable form that can be made useful only by means of decryption

Sería, nos dice, la última línea de defensa ante la posibilidad de que alguien consiga saltarse los sistemas de control de acceso y otras protecciones.

It is the last line of defense after an attacker has managed to break through authorization systems and access control.

Nos recuerda que los datos pueden estar cifrados en reposo, cuando están almacenados, y también cuando se transmiten por la red.

Data can be encrypted at-rest, such as on disk, or in transit, such as between two parties communicating over the Internet.

Una cifra (o método de cifrado) sería el algoritmo que utilizamos para cifrar. Un ejemplo es AES256. Es lo que la mayoría de la gente piensa cuando hablamos de cifrado.

A cipher is the algorithm used for encryption. For example, AES256 is a cipher. The idea of a cipher is what most people will think of when it comes to encryption.

Un resumen es la transformación que se utiliza para ofuscar y alargar la contraseña antes de cifrarla.

A digest is basically a hash function that is used to scramble and lengthen the password (i.e., the encryption key) before it’s used by the cipher.

Sirve, nos dice, para crear un conjunto de contraseñas aleatorizadas (aunque las originales no lo sean) y de la misma longitud que serían más adecuada para almacenar cifrada.

Relacionado está el términino de sal, cuyo objetivo es que dos contraseñas que pueden ser iguales no se vean iguales después de aleatorizarlas. De esta manera, un atacante que conociera la clave de un usuario no podría darse cuenta de que hay otros que utilizan la misma.

Usually, salt is randomly generated for each key and stored with it. In order to match known hashes, the attacker would have to precompute rainbow tables for a great many random values, which is generally not feasible.

Con la mejora de la potencia de cálculo ha surgido la idea de iterar los cálculos: no nos quedamos ocn una sola aplicación de la transformación sino que se hacen muchas, de forma que alguien que intentara un ataque por fuerza bruta lo tenga más difícil.

This is done many times so to make it computationally difficult for an attacker to reverse-guess the key, hence “iterations” (plural).

El vector de inicialización es un valor aleatorio que se utiliza para el cifrado de cada mensaje: a partir de la clave y del mensaje conseguiremos que diferentes incializaciones provoquen resultados diferentes, incluso aunque el mensaje sea el mismo.

IV (or “Initialization Vector”) is typically a random value that’s used for the encryption of each message. Now, salt is used for producing a key based on a password.

Esto permite evitar los ataques de repetición, puesto que el mismo mensaje repetido no produciría el mismo resultado, que es lo que intentan los atacantes cuando capturan un mensaje (incluso cifrado) y tratan de conseguir la misma acción repitiéndolo.

This makes “replay” attacks difficult, which is where the attacker doesn’t need to decrypt a message; rather, an encrypted message was “sniffed” (i.e., intercepted between the sender and receiver) and then replayed, hoping to repeat the action already performed.

Después de esta introducción muestra algunos ejemplos de aplicación, que valdría la pena mirar con calma.

Complejidades y carga cognitiva

Mecanismo

En Cognitive load is what matters se hablar de la carga cognitiva del desarrollo, que tiene que ver con lo que la persona que desarrolla tiene que pensar para completar su tarea.

Cognitive load is how much a developer needs to think in order to complete a task.

Cuando desarrollamos programas (software) podemos acudir a muy diversos niveles de abstracción. Manejamos infomación como valores, control del flujo y secuencias de llamadas, pero nuestra cabeza puede manejar esto hasta un cierto nivel.

When reading code, you put things like values of variables, control flow logic and call sequences into your head. The average person can hold roughly four such chunks in working memory. Once the cognitive load reaches this threshold, it becomes much harder to understand things.

Hay dos tipos de carga, la intrínseca, provocada por la dificultad de la tarea.

Intrinsic - caused by the inherent difficulty of a task. It can’t be reduced, it’s at the very heart of software development.

Y extrínseca, que tiene que ver con la forma en que se presenta la información, y que es sobre la que podríamos intervenir.

Extraneous - created by the way the information is presented. Caused by factors not directly relevant to the task, such as smart author’s quirks. Can be greatly reduced. We will focus on this type of cognitive load.

Por ejemplo, podríamos reducir expresiones lógicas complejas mediante la adición de variables que simplifiquen el proceso y nos den pistas. Copio sus ejemplos:

Complicado:

if val > someConstant // 🧠+
&& (condition2 || condition3) // 🧠+++, prev cond should be true, one of c2 or c3 has be true
&& (condition4 && !condition5) { // 🤯, we are messed up by this point
...
}

Más sencillo:

isValid = val > someConstant
isAllowed = condition2 || condition3
isSecure = condition4 && !condition5
// 🧠, we don't need to remember the conditions, there are descriptive variables
if isValid && isAllowed && isSecure {
    ...
}

Y se puede simplificar de más formas, pero creo que se ve la idea.

También nombra las salidas prematuras (early returns) que tanto les gustan a las inteligencias artificiales (o, al menos, eso es lo que he visto).

También puede haber otros tipos de complejidad relacionados con algunas construcciones que son ventajosas, como la herencia (que si se nos va de las manos puede obligarnos a llevar en la cabeza varios lugares del código donde pasan cosas interesantes.

Inheritance nightmare

¿Y qué sucede cuando tenemos demasiados métodos pequeños, clases y módulos? Demasidado de cualquier cosa (por mucho que los consejos nos recomienden tener métodos pequeños, compartimentalización, …) es un problema en sí mismo.

Having too many shallow modules can make it difficult to understand the project. Not only do we have to keep in mind each module responsibilities, but also all their interactions. To understand the purpose of a shallow module, we first need to look at the functionality of all the related modules. 🤯

Habla de otros casos relacionados como la exitencia de muchos microservicios en contraposición con un ‘monolito’ bien diseñado.

A well-crafted monolith with truly isolated modules is often much more flexible than a bunch of microservices. It also requires far less cognitive effort to maintain.

Otro caso interesante es el de los lenguajes con muchas características: lo que a priori parece una buena idea, resulta en un problema a la hora de aprender cosas nuevas, decidir cuáles usar, cómo, dónde…

You not only have to understand this complicated program, you have to understand why a programmer decided this was the way to approach a problem from the features that are available. 🤯

Un buen ejemplo es el de los códigos de respuesta del protocolo HTTP: por un lado son amplios y flexibles, pero al final vuelve a ocurrir lo mismo. Los desarrolladores usan menos porque es más sencillo para ellos, y los consumidores no son capaces de diferenciar los pequeños detalles que los diferencian, cuando probablemente sería mucho mejor devolver otro tipo de información.

Why hold this custom mapping in our working memory? It’s better to abstract away your business details from the HTTP transfer protocol, and return self-descriptive codes directly in the response body

Termina hablando de las arquitecturas con nivels (Layered architecture), donde la abstracción que nos ayuda a ocultar la complejidad añade indirecciones (y dificultades cuando estamos buscando problemas).

Abstraction is supposed to hide complexity, here it just adds indirection. Jumping from call to call to read along and figure out what goes wrong and what is missing is a vital requirement to quickly solve a problem.

El compromiso que suponen las ventajas frente a las difultades, que solo puede resolver la experiencia y el conocimiento.

So, why pay the price of high cognitive load for such a layered architecture, if it doesn’t pay off in the future?

He hecho un resumen, pero creo que es un buen resumen-recordatorio de cuestiones que deberíamos tener claras a la hora de abordar proyectos. Salvo que esos proyectos sean, precisamente, para aprender estas cosas.

Los datos de los mapas de Google, la privacidad y su persistencia

Mapa publicitario

Todos los consejos de privacidad recomiendan desactivar el almacenamiento de localización de Google. Sin embargo, yo me declaro un gran fan de la cosa: no es la primera vez que queriendo recordar los detalles de cuándo estuve dónde he tenido que buscar en el historial de alguien cercano porque lo tuve desactivado durante una época.

Hace unos meses Google decidió cambiar el sistema para que la localización se almacenara en nuestro propio dispositivo, en lugar de en su nube: sería, en principio, más amable con nuestra intimidad, pero solo un poco. A cambio, nos enfrentamos al problema que tiene responsabilizarnos de nuestros datos (que poca gente lo dice cuando habla de estas cosas): pérdida del dispositivo, degradación por algún motivo… Se soluciona, claro, subiendo (de otra forma) la copia a la nube y terminamos con un viaje de ida y vuelta.

Lo que no esperábamos es que el cambio provocara problemas a los usuarios y que el historial de localización de un buen número de personas, como nos contaban en Google Timeline location purge causes collateral damage se haya perdido.

Nos dicen que este cambio no garantiza la privacidad (lo decíamos arriba, lo de un poco) porque para eso Google tendría que dejar de mirar los datos que le puedan interesar para lo que sea.

The privacy afforded by this transition is somewhat overstated, though, because turning Timeline/Location History off doesn’t preclude Google’s collection and storage of data that reveals the user’s location directly or indirectly.

Nos dicen que el tiempo de retención de los datos se reduciría a 3 meses.

In addition to no longer storing Timeline data in the cloud by default, Google changed the default retention period – for Timeline/Location History and Web & App Activity, if turned on by the user – to three months,

Pero el problema es que en el cambio ha provocado las pérdidas que decíamos antes.

Despite the advance warning, complaints about missing data abound. And the loss of that data has been difficult for some. Numerous threads on Reddit and in Google’s support forum over the past few months lament the loss of Google Maps location history.

Y, aunque mi ejemplo no era muy interesante, lo cierto es que hay gente que utiliza estos datos para las tareas más diversas (cálculo de impuestos, recuerdos como los míos). Pero también hay casos más extremos, de personas con enfermedades que lo necesitan para su vida diaria.

“In early 2022, I suffered a brain injury when a flesh-eating bacteria invaded my prefrontal cortex and killed about 5 percent of my brain,” one reader told The Register, asking not to be identified. “I have very limited spatial memory now, and I utilized Google Timeline on the desktop for years to help me figure out where I’ve been three days ago, for the last week, month, etc. Without this, I can’t keep track of my life.”

También está el inconveniente de que la versión del navegador tampoco nos sirve ya para recordar esta información que es valiosa a veces.

Before December 8, Sam said, Google Maps on desktop would tell you when you visited a place. Until about five months ago, the app would also show photos from Google Photos.

Yo, desde luego, vivo con ‘miedo’ de perder esos datos desde que sucedió el cambio. Me he aficionado a poder consultarlos y utilizarlos de vez en cuando.

Los gestores de proyectos de software libre y la presión

Trabajando

Es un tema que ya lleva tiempo comentándose, pero me gustó leer Open source maintainers are really feeling the squeeze donde se comenta sobre el problema de que muchos desarrolladores de software libre sean voluntarios y como, en muchos casos, se les exige que trabajen como si fueran empresas responsables de desarrollos multimillonarios.

The theme cropped up repeatedly during 2025’s State Of Open Conference, with speakers from tech giants and volunteer maintainers laying out the challenges. Much of the open source ecosystem relies on volunteers putting in too many hours for too little support and the cracks are growing.

Se produjeron a principios de año algunas renuncias, como Hector Martín (De ashi Linux).

This week, the lead of the Asahi Linux project – a Linux distribution for Apple silicon – Hector Martin, abruptly quit, citing factors including developer burnout and demanding users.

Sus proyectos son valiosos y así lo sienten muchos usuarios, empresas y organizaciones, tanto como para presionar fuertemente cuando hay problemas.

The experience of feeling under pressure, isolated and faced with a growing pile of work while receiving the occasional unpleasant message from an entitled user demanding their issue be dealt with now or that a contribution merged be immediately is far too common.

Y a veces puede ser una cuestión de dinero, pero también sería intersante contar con otro tipo de colaboraciones que les quite presión y responsabilidades.

“Each maintainer and project has their own context and challenges - while many maintainers would benefit from financial support, others really could use more contributors to complement their work and remove responsibilities from them - especially for non-code tasks like mentorship, community management, issue triage, promotion and fundraising, etc.”

En contra del /tmp

El caracol de Juan

Es sabido que los sistemas de tipo Unix tienen un directorio común (pero un poco especial) que permite a cualquiera escribir para almacenar información de trabajo, ficheros temporales, …

En against /tmp comentan sobre el tema. Empiezan hablando de las peculiaridades, como es el sticky bit (¿pegajoso?) que es un permiso especial 01000 que se representa con una ‘t’:

drwxrwxrwt  5 root  wheel  160 Oct 22 10:22 /tmp/

Se inventó en los 70 para indicar que determinados programas debían permanecer en el núcleo porque eran de uso frecuente y así todo iba más fluido.

Originally in the 1970s the sticky bit was invented to speed up frequently-used programs such as the shell: the sticky bit indicated to the kernel that the executable file should stick in core. This functionality was made obsolete in the 1980s by filesystem page caches.

El bit se utilizó para los directorios con un objetivo diferente, impidiendo el borrado de ficheros aunque estuvieran en un directorio en el que tuviéramos permiso para borrar (el sistema de permisos de Unix siempre ha sido un poco básico).

To fix this, a file in a sticky directory may only be removed or renamed by a user if the user has write permission for the directory and the user is the owner of the file, the owner of the directory, or the super-user.

Esto es, el fichero en un directorio con el sticky bit solo puede borrarlo el propietario (o el propietario del directorio, o el administrador, claro).

Luego discute sobre las diferentes formas de crear un fichero temporal en Unix, con hasta cinco versiones diferentes:

bad: mktemp, tempnam, tmpnam ok: mkstemp, tmpfile new: mkdtemp, mkostemp, mkstemp

Tanto mkstemp como tmpfile están pensadas para crear ficheros (o directorios temporales) que no puedan colisionar con la actividad de otros programas.

The purpose of all these functions is to create a temporary file (or directory) that doesn’t collide with other concurrent activity.

El objetivo es evitar, fundamentalmente, condiciones de carrera (alguien consigue que abramos un fichero sobre el que tiene el control); para ello, hay que creaa nombres difíciles de predecir, con las restricciones adecudadas O_CREAT | O_EXCL, y hacer reintentos si el fichero ya existe EEXIST, para evitar (también) la denegación de servicio.

Luego discute sobre la limpieza (borrar lo que ya no se necesita) porque el /tmp tiene tendencia acumular basura y los problemas que puede tener alguien que intenta mantener ese directorio con los borrados.

Lo que debería suceder, afirma, es que debería haber directorios temporales diferenciados para cada usuario.

If you have per-user $TMPDIR then temporary filenames can safely be created using the simple mechanisms described in the mktemp(1) rationale or used by the old deprecated C functions. There’s no need to defend against an attacker who doesn’t have sufficient access to mount an attack! There’s no need for sticky directories because there aren’t any world-writable directories.

Y la razón de que eso no se hiciera tiene que ver (otra vez) con las prestaciones y los límites de los usuarios: podía ocurrir que el espacio del usuario estuviera montado a través de la red (lentitud), tuvier limitaciones de espacio (cuotas), o en un sistema de ficheros que no permitiera algunas características necesarias (como las named pipes).

Interesante. Un poco de historia, un poco de seguridad,…