Note Taking (II). Retos
Hace unos meses comencé a crear Note Taking, una aplicación cuyo propósito era la creación de un software que permitiera crear notas encriptadas de una manera sencilla y segura.
Surgió como un prototipo sobre el que fui iterando hasta llegar a lo que es hoy día: una plataforma relativamente estable, simple y segura para crear notas.
Pese a que el concepto es sencillo, en la ejecución lo está todo. Y ahí se yace el propósito de este artículo: mostrar los retos que me he encontrado en este camino.
seguridad
La seguridad es sin duda uno de los apartados más importantes y complejos de este software. A día de hoy el sistema utilizado es el siguiente:
Este sistema actualmente funciona bien:
- Todas las contraseñas tienen una alta entropía gracias al uso de Argon2 (un KDF).
- pwbox se encarga de encriptar las notas usando el resultado derivado de la contraseña original.
Pero ello no implica que tenga algunos problemas, en especial la imposibilidad de cambiar contraseñas.
cambio de contraseñas
En un software como este, es frecuente que el usuario quiera cambiar de contraseñas ocasionalmente por variadas razones: cambio rutinario preventivo, contraseñas que han sido expuestas, etc.
El sistema actual impide que esto sea posible, pues la contraseña es la base de la encriptación. A día de hoy para poder cambiar la contraseña sería necesario ir nota por nota desencriptándola y reencriptándola. Esto es un proceso que puede parecer sencillo, pero en cuanto el número de notas crece, una operación de este tipo se vuelve imposible de manejar.
posibles soluciones
Existen varios caminos que se pueden tomar para solucionar esto, pero el que creo que va a ser utilizado va a ser el siguiente:
Cada nota contiene una clave única que es la utilizada para encriptar los contenidos de la misma. Esta clave única, antes de ser almacenada en los metadatos de la nota pasa por el sistema descrito anteriormente.
Esto permite lo siguiente:
- Cada nota tiene su clave única de encriptación, por lo tanto, un ataque de fuerza bruta directamente en la nota pierde utilidad.
- El uso de una clave de encriptación única y permanente por nota permite que el cambio de la contraseña solo tenga que afectar a un centenar de bits en lugar de varios miles de bits, pues únicamente habría que reencriptar la clave de cada nota.
metadatos
A día de hoy, todos los metadatos (título, metadatos explícitos, fecha, etc) están sin encriptar. Esto es algo bastante delicado, pues muchas veces los metadatos son mucho más dañinos de lo que nos podemos imaginar.
Tengo pensado crear un archivo especial para las notas que pueda contener todas las notas de una manera centralizada y segura. En un principio una nota tendría una estructura similar a la siguiente:
- Longitud de la clave encriptada
- Clave encriptada
- Longitud de los metadatos
- Metadatos en JSON encriptados
- Longitud de la nota
- Nota encriptada
- Checksum de la nota
Además de esto, el archivo estaría versionado y trataría de ser lo más escalable posible en lo que a futuros metadatos especiales (fecha, autor, etc) respecta.
riqueza
A día de hoy las notas son simplemente texto plano. Otra de las cosas que tengo pensadas añadir es soporte básico de
Markdown (únicamente cosas como negrita, cursiva, tachado, etc.)
Me encantaría añadir soporte para imágenes, pero usando Markdown estándar es peligroso para la seguridad de los usuarios. Una alternativa sería aprovechar la creación de un archivo personalizado para añadir una sección de información arbitraria que funcionara como un diccionario, donde cada conjunto de datos arbitrarios tuviera asociado un identificador único que pudiera ser referenciado en Markdown.
Pese a ello, esto abre un gran vector de ataque que habría que cuidar, por tanto, el soporte de imágenes es algo que seguramente tendrá que esperar.
conclusión
Sin duda crear este software está siendo una experiencia bastante interesante que me está ayudando a aprender sobre seguridad computacional y muchas otras cosas.
A lo largo de los meses venideros trataré de implementar estas y más cosas, subiré una actualización cuando ello ocurra :)