trigger - mysql encrypt password
Columnas encriptadas MySQL (7)
Digamos que cada fila en una tabla tiene datos pertenecientes a un usuario en particular. El usuario tiene una contraseña para acceder al sistema.
¿Cómo encripto una columna de datos usando InnoDB para que nadie más que el usuario de quien es la información pueda leer los datos? Estaba pensando en algo así como usar una de las funciones de cifrado de MySQL (por ejemplo, AES) con una clave basada en un hash calculado a partir de la contraseña del usuario.
¿Alguien tiene alguna sugerencia de cómo podría hacer esto? ¿Estoy en el camino correcto?
Una de las respuestas a continuación
El problema de la modificación de la contraseña del usuario implica volver a cifrar la clave del usuario mediante la nueva contraseña, que es mucho más sencilla que volver a cifrar toda la información del usuario que puede ser arbitrariamente grande. La clave del usuario sigue siendo la misma a lo largo de la vida de los datos del usuario en el sistema.
¿Cómo ayuda esto? Diga que la contraseña es pass1. Y hay un montón de registros cifrados con una clave generada a partir de esto. Si el usuario ahora restablece la contraseña para pasar2, no tengo forma de descifrar los datos que se encriptaron usando pass1. En el caso de que un usuario olvide la contraseña por completo, se perderán todos sus datos encriptados.
No creo que sea el mejor enfoque, a menos que esté imponiendo que los usuarios nunca puedan cambiar su contraseña, o que tenga una forma de volver a encriptar todo cada vez que un usuario cambie su contraseña.
No sé si tiene mucho sentido cifrar datos con el hash de contraseñas del usuario, especialmente si mantiene el hash en la base de datos. En ese caso, cualquiera que pueda acceder a los datos cifrados también puede acceder al hash de la contraseña y descifrar los datos.
Otro enfoque sería cifrar los datos con la clave específica de la aplicación salada con algunos datos específicos del usuario. Sin embargo, entonces se enfrenta a otro problema: cómo almacenar de forma segura la clave de la aplicación. A esa pregunta no conozco una respuesta fácil, pero mantenerla en su código fuente es probablemente lo suficientemente buena si teme que los datos de su base de datos se vean comprometidos, pero no el código fuente en sí, por ejemplo, si su base de datos se almacena fuera del sitio ( piensa Amazon S3).
Salar la clave de la aplicación con la contraseña del usuario ayuda si solo conserva el hash de la contraseña en la base de datos, pero puede presentar otro defecto de seguridad: debe mantener la contraseña del usuario en texto claro en la sesión de las aplicaciones.
En cuanto a la solución técnica, es bastante simple y el código de muestra está disponible . Puede modificarlo de la siguiente manera para cifrar los datos con la contraseña de la aplicación salteada con hash de contraseña:
INSERT INTO secure_table VALUES (
1,
AES_ENCRYPT(
''plain text data'',
CONCAT(@application_password, @user_password))
);
En cualquier caso, tendría que guardar la contraseña de su aplicación en algún lugar, así que no creo que haya un enfoque fácil que proporcione una seguridad perfecta.
Otro enfoque en el que puedo pensar es pedirle al usuario un PIN corto que podría usar como clave de encriptación. El PIN no se almacenará en la base de datos, pero deberá solicitarlo al usuario cada vez que acceda a sus datos.
Y, por supuesto, tienes que pensar en la viabilidad del cifrado. No podrá indexar ni buscar sin descifrado. Probablemente se requiera para un conjunto limitado de datos (por ejemplo, número de tarjeta de crédito), pero no llegaría lejos con eso.
Puede almacenar otra clave para cifrar / descifrar datos específicos del usuario que podrían generarse cuando se crea un nuevo usuario. Llamemos a esta nueva clave de usuario clave. Esta clave de usuario también debe encriptarse en la base de datos y el enfoque más directo sería codificarla mediante la contraseña del usuario o cualquier otro dato que contenga la contraseña (como la contraseña y el tiempo de creación / modificación, etc.).
Mantendría en la sesión del usuario la clave de usuario descifrada para acceder a los datos del usuario en cualquier momento de la sesión.
El problema de la modificación de la contraseña del usuario implica volver a cifrar la clave del usuario mediante la nueva contraseña, que es mucho más sencilla que volver a cifrar toda la información del usuario que puede ser arbitrariamente grande. La clave del usuario sigue siendo la misma a lo largo de la vida de los datos del usuario en el sistema.
Por supuesto, este método solo se puede usar si la autenticación se lleva a cabo enviando la contraseña de usuario real al servidor al inicio de sesión, ya que la base de datos solo contiene deseablemente el hash de la contraseña.
Diga que la contraseña es pass1. Y hay un montón de registros cifrados con una clave generada a partir de esto. Si el usuario ahora restablece la contraseña para pasar2, no tengo manera de descifrar los datos que se encriptaron usando pass1
La clave debería cifrarse de manera reversible, de modo que se pueda descifrar usando pass1 y volver a cifrar con pass2.
Para resumir:
Almacenado en la base de datos está: la contraseña encriptada de una vía (para verificar contraseñas), la clave de encriptación para otros datos, encriptada reversiblemente usando la contraseña clara (o, en todo caso, la contraseña encriptada de una manera diferente a la guardada) en la base de datos) y los demás datos, cifrados de forma reversible con la clave de cifrado sin cifrar.
Cuando necesite los demás datos, debe tener la contraseña clara (o cifrada de forma diferente a la almacenada en la base de datos), leer la clave de cifrado, descifrarla con la contraseña y usarla para descifrar los demás datos.
Cuando se cambia una contraseña, la clave de cifrado se descifra utilizando la contraseña anterior, se cifra con la nueva contraseña y se almacena.
Para aclarar una de las respuestas mencionadas en la pregunta: "usuario / clave de la aplicación" es una clave privada generada aleatoriamente, que se utiliza para encriptar los datos. La clave privada nunca cambia (a menos que esté comprometida). Usted encripta y almacena la clave privada con una contraseña. Como la clave privada es mucho más pequeña que los datos, es mucho más económico cambiar la contraseña: simplemente descifra la clave privada con la contraseña anterior y la vuelve a encriptar con la nueva contraseña.
Si necesita acceder a los datos sin la interacción del usuario (para la migración de la base de datos, por ejemplo), no tendrá la clave para descifrar.
Para los datos que no son específicos del usuario (global), tal vez podría usar una combinación de cifrado simétrico y asimétrico. Puede tener un campo de extra password
que todos los usuarios deben ingresar para que, incluso si un usuario cambia la contraseña, los datos globales podrán ser utilizados por otros usuarios con diferentes contraseñas.
La extra password
se puede ordenar por bit con otra salt-like string
dentro del código fuente. Juntos, pueden formar la clave simétrica para descifrar una private key
almacenada en la base de datos (que nunca cambiará). Después de descifrar private key
con la extra password
, la clave privada puede descifrar y read
todos los datos en el archivo db. La clave privada se puede almacenar como variable de sesión.
La public key
, como su nombre lo sugiere, puede residir como cadena de texto sin formato en el archivo db. Cuando necesite write
en db, use la clave pública para encriptar los datos.
Puede proporcionar rutinariamente a los usuarios una nueva extra password
y volver a cifrar la private key
estática, seguida de un xor''ing con una cadena similar a la salt-like string
.
Si los datos son datos específicos del usuario y no están destinados a otros usuarios, puede usar la contraseña del usuario sin el campo de contraseña adicional para encriptar la clave privada. El administrador podría tener otra copia de las claves privadas para usuarios específicos, que se puede descifrar usando su contraseña.