Cifrado seguro pero reversible para el almacén de datos local

4

Estoy trabajando en un software para almacenar y administrar registros para un grupo de jóvenes. Descubrieron que gran parte del tiempo que dedican al mantenimiento de registros y administración se dedica a la exploración en busca de diversas condiciones, como "es más antiguo que X años y tiene calificación de Y" o "ha sido miembro durante X años. y ha realizado el evento Y más de dos veces ", o" ha realizado los eventos X, Y y Z y, por lo tanto, necesita el premio A ". Como programador, reconocí que este tipo de cosas podrían manejarse fácilmente con una computadora, lo que les ahorra horas de trabajo, por lo que estoy creando una aplicación para que se encargue de ello.

Hasta ahora, sus registros se han mantenido en papel o en hojas de cálculo Excel, por lo que se podría argumentar que no necesito cifrar nada porque no estaban cifrados antes, pero no me siento del todo cómodo. con la redacción de un programa que almacena información sobre niños menores de edad (de 14 a 18 años, aproximadamente) sin tener una forma de controlar quién puede obtener esa información.

Nunca antes había hecho el cifrado, así que no estoy seguro de por dónde empezar. He implementado numerosos esquemas de administración de contraseñas, por lo que estoy familiarizado con algunos de los principios, pero que usan métodos de cifrado de una sola vía y de tipo no cifrado como hashes, ninguno de los cuales puede usarse aquí porque necesito poder obtener los datos de nuevo. Lo mejor que se me ocurre es usar una contraseña (más sal) en texto plano como la clave para cifrar en algún esquema de dos vías, pero luego solo almacene el hash de esa contraseña para verificar el inicio de sesión. Sin embargo, la contraseña se almacenará en la memoria mientras se ejecuta el programa, y me gustaría reducir la cantidad de tiempo en que la contraseña es en cualquier lugar distinta de la memoria del usuario.

Comprendo que colocar estos datos en un lugar que no sea un servidor que pueda controlar aumenta el riesgo, pero necesito que estos datos estén disponibles sin conexión. ¿Alguien puede explicar una forma sólida de almacenar estos datos?

    
pregunta anaximander 20.04.2013 - 16:14
fuente

2 respuestas

1

Puede recurrir a una base de datos MySQL para aprovechar su compatibilidad con criptografía .

Luego tienes dos opciones (en realidad puedes emplear ambas):

1) Algunos datos se pueden dejar en texto sin formato, pero anonymized , es decir, no hay forma de saber a quién se refieren los datos.   2) Otros datos están encriptados, utilizando un algoritmo simétrico. La clave para hacerlo será aleatoria y se cifrará con la contraseña del usuario. De esta manera, varios usuarios pueden acceder a los mismos datos

User    Password   CryptoKey
alice   <hash1>    <encrypt(pwd1, RANDOM)>
bob     <hash2>    <encrypt(pwd2, RANDOM)>

Para autenticarse, Alice envía su contraseña, que se verifica con el hash almacenado. Si es válido, la clave RANDOM se extrae y se almacena en la memoria del servidor durante la sesión.

Los campos de texto y BLOB se pueden cifrar (con o sin sal). Los campos cortos o los campos con cardinalidad baja están mejor salados; de lo contrario, los contenidos se pueden adivinar fácilmente: por ejemplo, un campo que contiene 'Masculino' o 'Femenino', después de que el cifrado sin sal pueda contener 'e3290d6cd47a701168b962aa0c6b249e' o 'd87d344d4808900421c93de197kcra solo dos valores, que es una vulnerabilidad potencial.

Cambiar la contraseña de Alice no es gran cosa; por supuesto, si RANDOM se expone, eso es un gran problema. Las comunicaciones con el front-end deben pasar por SSL / TLS y contener datos descifrados por RANDOM (pero encriptados por SSL), protegiendo así la seguridad de RANDOM, que nunca abandona el servidor.

No hace falta decir que el acceso físico a la memoria del servidor comprometerá todo, ya que sería fácil realizar un ataque de hombre en el medio y engañar a un usuario válido para que revele su contraseña, de la que se puede obtener RANDOM. y el almacén de datos descifrado.

Opcionalmente, puede cifrar también la conexión a la base de datos , pero eso parece un poco como una exageración (probablemente serán locales de todos modos) y aún así no lo protegerá contra la explotación del servidor.

Los datos se pueden sincronizar entre una base de datos MySQL local y remota sin saber la contraseña, ya sea descargando un volcado de base de datos (que es viable si el tamaño de los datos es pequeño; recuerde que los datos cifrados no son comprimibles ) o manteniendo un registro de actualizaciones, que es mucho más difícil (piense que 'Alice en su computadora portátil modifica un registro mientras que Bob en su escritorio borra ese mismo registro, y Charlie inserta un nuevo registro con una nueva clave primaria ... ').

Francamente, la mejor solución que he encontrado en estos casos es colocar todo en un servidor confiable con un plan de respaldo adecuado y hacer que los clientes se conecten al servidor. Por lo general, en realidad es más rápido y económico proporcionar a los clientes desconectados conectividad a Internet que diseñar la base de datos para el uso sin conexión, la sincronización y la resolución de conflictos. Solo lectura las copias pueden ser entregadas, por supuesto. El servidor remoto generalmente se puede configurar para enviar correos electrónicos y ejecutar trabajos cron, e informar a los clientes de cualquier evento (por ejemplo, "Janie ha ganado el Premio A2").

Al exponer solo una interfaz REST, puede explotar varios marcos de aplicaciones y también tener una aplicación del lado del servidor más sencilla y fácil de probar (los puntos de entrada y las rutas de flujo de trabajo son pocos por diseño y se pueden enumerar), lo que reduce considerablemente la riesgo de explotación de un servidor.

Otra posibilidad

Dado que la base de datos maestra vive en un servidor central, y una copia de la misma vive localmente, puede mantener la aplicación y la base de datos en una clave USB externa y cifrada. La base de datos en sí no tiene cifrado; podría utilizar SQLite localmente. Si usa MySQL, puede ejecutarlo a través de Aplicaciones portátiles o algo parecido.

Entonces, el flujo de trabajo sería: el usuario inserta la llave USB, que requiere una PIN o incluso una huella digital . Una vez desbloqueado, puede ejecutar la aplicación, que si es necesario (es decir, MySQL, PostgreSQL, ...) activará el servidor y se conectará a él; o accederá directamente a los datos (SQLite). Cuando haya terminado, el servidor (si lo hubiera) se detiene, la clave se expulsa y los datos en ella son prueba contra cualquier amenaza razonable.

Cuando vuelve al rango de conectividad, el usuario vuelve a encender la aplicación y la sincroniza con el servidor central.

Esta solución tiene la ventaja de que la seguridad es un complemento con un costo conocido. Los usuarios pueden decidir no pagar ese costo, pero es su decisión, no suya .

    
respondido por el LSerni 20.04.2013 - 18:41
fuente
3

Cifre los datos con un algoritmo fuerte como AES . Utilice pbkdf2 o bcrypt para derivar la clave de cifrado de una contraseña.

Necesita una forma de propagar y actualizar los datos, a menos que la solución sea solo para una sola computadora (si es así, siga con las hojas de cálculo de Excel. ¿Por qué molestarse en escribir una aplicación?). Haga que el cliente vuelva a conectarse al servidor para actualizar la base de datos y / o descargar nuevos datos de la base de datos. Haga que el cliente se autentique mediante certificados y asegure la conexión a través de SSL / TLS.

    
respondido por el Ayrx 20.04.2013 - 17:13
fuente

Lea otras preguntas en las etiquetas