Cifrado MySQL y gestión de claves

10

Estoy desarrollando un sistema de intranet local en PHP / MySQL para administrar los datos de nuestros clientes. Parece que la mejor práctica sería cifrar los datos confidenciales en el servidor MySQL a medida que se ingresan.

Sin embargo, no tengo claro cuál sería la mejor manera de hacer esto sin dejar de tener acceso a los datos.

Parece una pregunta difícil de responder: ¿dónde se almacenan las claves? ¿Cómo proteger mejor la clave? Si la clave se almacena en la máquina de cada usuario, ¿cómo protegerla si la máquina es explotada? Si se explota la clave, ¿cómo cambiarla?

Si la clave se va a almacenar en la base de datos, ¿cómo protegerla allí? ¿Cómo accederían los usuarios?

colector de aguas pluviales
fuente
El tipo de encriptación y almacenamiento de claves dependerá del tipo de escenarios que desee evitar. Obviamente, si su atacante obtiene usuario root o usuario de la aplicación en el servidor, puede usar las mismas rutinas para descifrar que usa su aplicación. Entonces, ¿qué escenario quieres evitar? Alguien robando la copia de seguridad? Ataque de inyección SQL? ¿Algo más?
Aleksandar Ivanisevic
¡Gracias por la respuesta! No estoy tan preocupado por las copias de seguridad. Me preocupa más que alguien explote la máquina de un usuario y luego acceda al sitio desde allí a través de la inyección de SQL, o desmintiendo las credenciales de la aplicación de un usuario. No me preocupa demasiado la máquina en sí; las credenciales para su son muy fuertes (sin embargo, no tengo la ilusión de que sea 100% seguro).
stormdrain

Respuestas:

9

Realmente no hay ninguna característica incorporada de MySQL para manejar configuraciones sofisticadas de claves cifradas. Deberá implementar la mayor parte de la lógica de cifrado en su propio código PHP y / o del lado del navegador (javascript?).

Pero sus preocupaciones expresadas son ligeramente peculiares: parece que sus únicas preocupaciones reales son una inyección SQL o un ataque de fuerza bruta (adivinación de contraseña, supongo) desde una estación de trabajo de escritorio / computadora portátil remota del cliente. Eso me hace sospechar que ya tiene planeadas otras medidas de seguridad no mencionadas, y que ha analizado las posibles vías de compromiso.

  • Por un lado, supongo que tiene reglas de firewall que protegen el host MySQL / PHP contra cualquier tipo de acceso desde IP de clientes remotos no aprobados. Si estoy en lo cierto, tiene sentido que solo le preocupen los ataques de las estaciones de trabajo de los usuarios comprometidos.

  • Además, supongo que comprende que si un atacante en el host del cliente remoto puede escalar a root / Admin privs, o comprometer directamente la cuenta del usuario real, entonces los datos del cliente tienen cero protección, independientemente del cifrado o cualquier otra protección. (El atacante puede leer las claves desde cualquier lugar donde estén guardadas en el disco, o espiarlas cuando el usuario real las ingresa al iniciar sesión, y las claves conducen a datos).

A partir de estos dos supuestos, tiene sentido que concluyamos que las únicas dos amenazas relevantes son A) adivinar la contraseña por fuerza bruta y B) los intentos de inyección de SQL:

  • Si el atacante no obtiene la clave del usuario real, o si desea acceder a más que solo los datos del usuario real, puede intentar acreditar el inicio de sesión por fuerza bruta para el usuario real u otra cuenta. (En teoría, podría bloquear cada cuenta a una IP de cliente remoto específica, lo que también ayudaría a compartimentar los riesgos).
  • Si el atacante obtiene una clave válida para el usuario real, tiene una vía más allá de la pantalla de inicio de sesión (que presumiblemente es lo suficientemente simple como para ser segura), hasta el punto débil del código de la aplicación potencialmente defectuoso. Una inyección SQL exitosa del contexto del usuario real también podría darle acceso a los datos de otros clientes.

Ahora, hablemos sobre cómo se aplica el cifrado del lado del servidor a estas situaciones:

  • El cifrado del lado del servidor definitivamente ayuda contra la amenaza de inyección SQL. Si los valores de las filas están encriptados en las tablas de la base de datos, el atacante solo puede ver el texto cifrado de los datos que pertenecen a otras cuentas. La amenaza está contenida, compartimentada.
  • Sin embargo, adivinar la contraseña de forzamiento bruto realmente no se vuelve más difícil para un atacante que enfrenta el cifrado del lado del servidor. Independientemente de si las claves de los usuarios se almacenan en el servidor o se generan en el acto a partir de la contraseña, lo único que importa es si tiene la contraseña correcta. O el servidor decide permitirle usar la clave almacenada válida porque verifica que su contraseña sea correcta, o calcula la clave válida para usted porque su contraseña es la entrada correcta para generar esa clave.

El cifrado del lado del cliente, por otro lado, hace que los ataques de contraseña de fuerza bruta sean irrelevantes. No se puede forzar con fuerza bruta una clave construida correctamente. El cifrado del lado del cliente también mantiene básicamente el mismo nivel de protección contra la inyección de SQL que el cifrado del lado del servidor. El cliente puede pasar la clave al servidor al iniciar sesión, manteniendo una copia en la memoria hasta que finalice la sesión, lo que pone la carga de la CPU criptográfica en el servidor. O bien, el cliente puede manejar el cifrado / descifrado por sí mismo, en el navegador. Hay altibajos en ambas técnicas:

  • Pasar su clave al servidor es mucho más fácil de codificar y administrar, y generalmente es mucho más rápido debido a un código criptográfico más optimizado (C compilado, probablemente).
  • Un enfoque puro del lado del cliente brinda seguridad adicional, porque incluso si un atacante obtiene root en el servidor, aún no puede leer los datos cifrados y nunca podrá leerlos. El único vector de ataque posible es comprometer la estación de trabajo del cliente remoto.

Finalmente, voy a notar que hay algunas desventajas operativas enormes para cifrar datos en la base de datos. Debido a que las representaciones de datos encriptados son esencialmente patrones aleatorios, las funciones básicas de la base de datos como indexación, uniones, etc. no funcionarán. El cliente asume una enorme carga lógica y puede perder muchos de los beneficios que las características de la base de datos normalmente aportan.

Ryan B. Lynch
fuente
1
¡Guauu! Respuesta asombrosa y minuciosa; muchas gracias. En los últimos días, he estado considerando algunas opciones y he decidido intentar implementar una solución del lado del cliente como usted sugirió. Idealmente, las claves se almacenarán en unidades de memoria USB que solo se montarán mientras un usuario esté trabajando en el sistema (la seguridad física es muy estricta) y la clave se mantendrá en la memoria solo mientras dure la sesión. Idea es que las claves sólo se podrá acceder al sistema durante las horas de trabajo cuando estoy allí para vigilar el tráfico, etc.
Stormdrain
2

Es posible que desee ver ezNcrypt , que utiliza ecryptfs, controles de acceso y administración de claves para proporcionar alta seguridad y rendimiento para el cifrado Linux de bases de datos MySQL y otros procesos. No, no trabajo para ellos.

Dan
fuente
2

Podrías usar Scytale. Es un proxy criptográfico NoSQL para DBMS y aplicaciones web modernas. Admite el cifrado de múltiples destinatarios y grupos. Cargado con un fuerte sistema criptográfico RSA / AES. También es 100% gratuito y de código abierto.

https://bitbucket.org/maximelabelle/scytale

Maxime Labelle
fuente