2010-09-11 6 views
5

Estoy escribiendo una aplicación cuyo objetivo principal es mantener la lista de usuarios compras.¿Cómo separar la identidad de una persona de sus datos personales?

quisiera asegurar que incluso como desarrollador (o cualquier persona con plena acceso a la base de datos) no se podía calcular la cantidad de dinero que una persona en particular ha pasado o lo que él ha comprado.

inicialmente me ocurrió con el siguiente esquema:

 
    --------------+------------+----------- 
    user_hash  | item  | price 
    --------------+------------+----------- 
    a45cd654fe810 | Strip club |  400.00 
    a45cd654fe810 | Ferrari | 1510800.00 
    54da2241211c2 | Beer  |  5.00 
    54da2241211c2 | iPhone  |  399.00 
  • usuario inicia sesión con nombre de usuario y contraseña.
  • De la contraseña calcule user_hash (posiblemente con salazón, etc.).
  • Use el hash para acceder a los datos de los usuarios con consultas SQL normales.

Dado el número suficiente de usuarios, sería casi imposible saber cuánto dinero ha gastado un usuario en cuestión por solo con solo saber su nombre.

¿Es esto algo sensato de hacer, o soy completamente tonto?

+0

¿Qué es "infromation"? ;) – MPelletier

+0

Gracias, error ortográfico corregido. –

+0

Por favor, siéntase libre de preguntar si la pregunta no es lo suficientemente clara. O si piensa/siente/asume que probablemente no hay solución para este problema: adelante y dígalo. –

Respuesta

0

El problema es que si alguien ya tiene acceso completo a la base de datos, es solo cuestión de tiempo antes de vincular los registros a personas determinadas. En algún lugar de su base de datos (o en la propia aplicación), deberá establecer la relación entre el usuario y los elementos. Si alguien tiene acceso completo, entonces tendrá acceso a ese mecanismo.

No hay forma de prevenir esto.

La realidad es que al tener acceso completo estamos en una posición de confianza. Esto significa que los gerentes de la compañía deben confiar en que, aunque usted pueda ver los datos, no actuará de ninguna manera con ellos. Aquí es donde entran en juego pequeñas cosas como la ética.

Ahora, dicho esto, muchas compañías separan al personal de desarrollo y producción. El propósito es eliminar el Desarrollo de tener contacto directo con datos en vivo (es decir, reales). Esto tiene una serie de ventajas, ya que la seguridad y la confiabilidad de los datos están en la parte superior del heap.

El único inconveniente real es que algunos desarrolladores de creen que no pueden solucionar un problema sin acceso de producción. Sin embargo, esto simplemente no es verdad.

El personal de producción sería el único con acceso a los servidores en vivo. Por lo general, serán investigados en mayor grado (antecedentes penales y otras verificaciones de antecedentes) que se compadezca con el tipo de datos que debe proteger.

El objetivo de todo esto es que se trata de un problema de personal; y no uno que pueda ser realmente resuelto con medios técnicos.


ACTUALIZACIÓN

otros aquí parece que falta una pieza muy importante y vital del rompecabezas. A saber, que los datos se ingresan en el sistema por algún motivo. Esa razón es casi universal para que pueda ser compartida. En el caso de un informe de gastos, los datos se ingresan para que la contabilidad pueda saber a quién devolver.

Lo que significa que el sistema, en algún nivel, tendrá que coincidir con los usuarios y los artículos sin la persona de entrada de datos (es decir: un vendedor) estando conectado

Y debido a que los datos tienen que ser atados juntos sin. todas las partes involucradas allí para escribir un código de seguridad para "liberar" los datos, entonces un DBA será absolutamente capaz de revisar los registros de consulta para descubrir quién es quién. Y muy fácilmente podría agregar independientemente de la cantidad de marcas de almohadilla que desee agregar. Triple DES tampoco lo salvará.

Al final del día, todo lo que ha hecho es hacer el desarrollo más difícil con absolutamente cero beneficio de seguridad. No puedo enfatizar esto lo suficiente: la única forma de ocultar datos de un dba sería para 1. que los datos a solo sean accesibles por la misma persona que los ingresó o 2. para que no existan en primer lugar .

En relación con la opción 1, si la única persona que puede acceder a ella es la persona que la ingresó ... bueno, no tiene sentido que esté en una base de datos corporativa.

+0

Eso es lo que también pensé ... pero es una pequeña startup con solo dos desarrolladores y no mucho más. –

+0

@Chris - El acceso a la base de datos no es lo mismo que el acceso completo. Esta información puede ocultarse a los administradores de bases de datos, pero es probable que alguien con acceso raíz o físico al servidor web pueda obtenerla. La Q se trata de proteger los datos de aquellos con acceso a la base de datos; Creo que es completamente factible. Por favor, mira mi respuesta, espero que pueda cambiar tu opinión. –

+0

No creo que no pueda solucionar los problemas sin tener acceso a los sistemas de producción, pero creo que puedo hacerlo mucho más rápido. Los problemas que podría localizar en minutos podrían requerir horas o días para intercambiar correos electrónicos con los DBA. – mikerobi

4

Me temo que si su aplicación puede vincular a una persona con sus datos, cualquier desarrollador/administrador puede hacerlo.

Lo único que puede hacer es dificultar el enlace para ralentizar al desarrollador/administrador, pero si dificulta el enlace de los usuarios con los datos, también lo hará más difícil para su servidor.


idea basada en la idea de @no:

Usted puede tener un/contraseña de inicio de sesión de usuario clásica a su aplicación (hash de la contraseña, o lo que sea), y un "pase" especial que se utiliza para mantener sus datos seguros . Este "pase" no se almacenará en su base de datos.

Cuando su cliente inicie sesión en su aplicación, tendría que proporcionar un usuario/contraseña/pase. El usuario/contraseña se verifica con la base de datos, y el pase se usará para cargar/escribir datos.

Cuando necesite escribir datos, haga un hash de su pareja "nombre de usuario/pase", y almacénelo como una clave que vincula a su cliente con sus datos.

Cuando necesite cargar datos, haga un hash de su pareja "nombre de usuario/pase" y cargue cada dato que coincida con este hash.

De esta manera es imposible hacer un enlace entre sus datos y su usuario.

Por otro lado, (como dije en un comentario a @no) tenga cuidado con las colisiones. Además, si su usuario escribe un "pase" malo, no puede verificarlo.


Actualización: Para la última parte, tenía otra idea, que puede almacenar en su base de datos un hash de su pareja "pasa/contraseña", de esta manera se puede comprobar si su "pase" está bien.

+0

Gracias por tomarse su tiempo para responder, pero la aplicación solo puede vincular a la persona con sus datos si conoce su contraseña (a partir de la cual puede calcular 'user_hash'). Tal vez debería haber aclarado que en la tabla 'users' no hay una columna' user_hash', a la que se puedan vincular datos de personas. –

+2

Si su aplicación puede hacer el hash, ¿por qué un desarrollador no pudo reescribir el mismo método hash para obtener el mismo resultado? Si sabe cómo acceder a él dentro de su aplicación, siempre puede volver a escribir este código para acceder a él con otra aplicación. –

+0

Sí, este enfoque no funcionará. Lo que hay que hacer es guardar el hash de la contraseña en la base de datos como de costumbre, pero use un hash diferente para las cosas delicadas. Ver mi respuesta. –

0

En realidad, hay una manera en que podrías hacer lo que estás hablando ...

Puede hacer que el usuario escriba su nombre y contraseña en un formulario que ejecuta un script puramente del lado del cliente que genera un hash basado en el nombre y pw. Ese hash se usa como una identificación única para el usuario y se envía al servidor. De esta forma, el servidor solo conoce al usuario por hash, no por su nombre.

Para que esto funcione, el hash debería ser diferente del hash de contraseña normal, y el usuario debería ingresar su nombre/contraseña un tiempo adicional antes de que el servidor tenga "memoria" de qué esa persona compró

El servidor podría recordar lo que compró la persona durante la duración de su sesión y luego 'olvidar', porque la base de datos no contendría ningún enlace entre las cuentas de usuario y la información confidencial.

edición

En respuesta a los que dicen hash en el cliente es un riesgo de seguridad: No es si lo haces bien. Se debe suponer que un algoritmo hash es conocido o cognoscible. Decir lo contrario equivale a "seguridad a través de la oscuridad". Hashing no implica ninguna clave privada, y los hash dinámicos se pueden usar para evitar manipulaciones.

Por ejemplo, se toma un generador de hash de la siguiente manera:

http://baagoe.com/en/RandomMusings/javascript/Mash.js

// From http://baagoe.com/en/RandomMusings/javascript/ 
// Johannes Baagoe <[email protected]>, 2010 
function Mash() { 
    var n = 0xefc8249d; 

    var mash = function(data) { 
    data = data.toString(); 
    for (var i = 0; i < data.length; i++) { 
     n += data.charCodeAt(i); 
     var h = 0.02519603282416938 * n; 
     n = h >>> 0; 
     h -= n; 
     h *= n; 
     n = h >>> 0; 
     h -= n; 
     n += h * 0x100000000; // 2^32 
    } 
    return (n >>> 0) * 2.3283064365386963e-10; // 2^-32 
    }; 

    mash.version = 'Mash 0.9'; 
    return mash; 
} 

Vea cómo n cambios, cada vez que hash de una cadena que llegue algo diferente.

  • Ingrese el nombre de usuario + contraseña utilizando un algoritmo hash normal. Esta será la misma que la clave de la tabla "secreta" en la base de datos, pero no coincidirá con nada más en la base de datos.
  • Agregue el hash pass al nombre de usuario y córtalo con el algoritmo anterior.
  • Base-16 codifica var n y añádelo en el hash original con un carácter delimitador.

Esto creará un hash único (será diferente cada vez) que puede ser verificado por el sistema contra cada columna de la base de datos. El sistema se puede configurar para permitir un hash exclusivo en particular solo una vez (por ejemplo, una vez al año), lo que previene los ataques de MITM, y ninguna información del usuario se pasa a través del cable. A menos que me esté perdiendo algo, no hay nada inseguro sobre esto.

+0

@Chris & Colin ... Ambos dicen que no hay forma de hacer esto. Por curiosidad, ¿puedes pensar alguna razón por la cual este enfoque no funcionaría? La base de datos no podría vincular a un usuario con sus registros privados, sino que le corresponde al usuario agregar información adicional (realmente solo su nombre de usuario y contraseña nuevamente) para que la base de datos obtenga esos registros. Tener acceso a la base de datos no sería suficiente para descubrir quién (por nombre) compró qué. –

+0

El gran problema que veo con esto es cuando el usuario cambia su contraseña, el hash (y por lo tanto, el único vínculo entre la cuenta y los datos) también cambia. Lo mejor sería usar un identificador que permanezca estático. Quizás si tuviera una base de datos adicional para asignar hashes de nombre de usuario/contraseña a los ID de usuario, entonces eso podría ser diferente. – bta

+0

Hum, este enfoque podría funcionar, pero ten cuidado con las colisiones hash. En este caso, podría ser realmente feo. –

1

La única manera de garantizar que los datos no se puedan conectar a la persona a la que pertenece es no registrar la información de identidad en primer lugar (anónima todo). Sin embargo, hacer esto hará que su aplicación no tenga sentido. Puedes hacer esto más difícil de hacer, pero no puedes hacerlo imposible.

Almacenar los datos de usuario y la información de identificación en bases de datos separadas (y posiblemente en servidores separados) y vincular los dos con un número de identificación es probablemente lo más cercano que puede hacer. De esta manera, ha aislado los dos conjuntos de datos tanto como sea posible. Aún debe conservar ese número de ID como un enlace entre ellos; de lo contrario, no podría recuperar los datos de un usuario.

Además, yo no recomendaría usar una contraseña hash como un identificador único. Cuando un usuario cambia su contraseña, debe pasar y actualizar todas sus bases de datos para reemplazar las viejas ID de contraseña hash con las nuevas.Por lo general, es mucho más fácil usar una ID única que no se basa en ninguna información del usuario (para ayudar a garantizar que permanezca estática).

Esto termina siendo un problema social, no un problema tecnológico. Las mejores soluciones serán una solución social. Después de fortalecer sus sistemas para protegerse contra el acceso no autorizado (hackers, etc.), es probable que obtenga un mejor millaje trabajando para establecer confianza con sus usuarios e implementando un sistema de políticas y procedimientos relacionados con la seguridad de los datos. Incluya penalidades específicas para los empleados que usan mal la información del cliente. Dado que una sola violación de la confianza del cliente es suficiente para arruinar su reputación y alejar a todos sus usuarios, la tentación de utilizar indebidamente esta información por parte de personas con acceso de "alto nivel" es menor de lo que podría pensar (ya que el colapso de la compañía supera cualquier ganancia).

+0

La idea de bases de datos separadas parece interesante. Por cierto, en realidad no tenía la intención de poner el hash real en una tabla de esta manera exacta, en lugar de usar una tabla intermedia que asigna hashes a los id-s de los usuarios. Pero simplifiqué mucho mi pregunta original, y esto se simplificó. –

2
  1. Crear una tabla con los usuarios:
    1. user_id: una columna de identidad (ID autogenerado)
    2. nombre de usuario
    3. contraseña: asegúrese de que está hash!
  2. Crear una tabla de productos como en su ejemplo:
    1. user_hash
    2. elemento
    3. precio

El user_hash se basa fuera de user_id que nunca cambia. El nombre de usuario y la contraseña son libres de cambiar según sea necesario. Cuando el usuario inicia sesión, se compara el nombre de usuario/contraseña para obtener el user_id. Puede enviar user_hash nuevamente al cliente durante la sesión o una versión cifrada/indirecta del hash (podría ser una ID de sesión, donde el servidor almacena el user_hash en la sesión).

Ahora necesita una forma de hash el user_id en user_hash y mantenerlo protegido.

  1. Si lo hace desde el lado del cliente como @no se sugiere, el cliente necesita tener user_id. Gran agujero de seguridad (especialmente si es una aplicación web), el hash puede manipularse fácilmente y el algoritmo está disponible libremente para el público.
  2. Puede tenerlo como una función en la base de datos. Mala idea, ya que la base de datos tiene todas las piezas para vincular los registros.
  3. Para sitios web o aplicaciones de cliente/servidor puede tenerlo en su código de servidor. Mucho mejor, pero luego un desarrollador tiene acceso al algoritmo y a los datos de hash.
  4. Pida a otro desarrollador que escriba el algoritmo hash (al que no tiene acceso) y que lo adhiera a otro servidor (al que tampoco tiene acceso) como un servicio TCP/web. El código del lado del servidor pasaría la identificación del usuario y obtendría un hash. No tendrías el algoritmo, pero puedes enviar todas las ID de usuario para recuperar todos sus hash. No muchos beneficios para el n. ° 3, aunque el servicio podría tener un registro y así intentar minimizar el riesgo.
  5. Si se trata simplemente de una aplicación de base de datos de cliente, solo tiene las opciones 1 y 2. Le sugiero que agregue otra capa [empresarial] que esté en el servidor, separada del servidor de la base de datos.

Editar: Esta solapa con algunos de los puntos anteriores.Tiene 3 servidores:

  • servidor de autenticación: Empleado A tiene acceso. Mantiene la tabla de usuarios. Tiene servicio web (con comunicaciones encriptadas) que toma la combinación de usuario/contraseña. Hashes password, busca user_id en la tabla, genera user_hash. De esta forma, no puedes simplemente enviar todos los user_ids y recuperar los hashes. Debe tener la contraseña que no está almacenada en ningún lugar y solo está disponible durante el proceso de autenticación.
  • Servidor de base de datos principal: El empleado B tiene acceso. Solo almacena user_hash. Sin ID de usuario, sin contraseñas. Puede vincular los datos usando user_hash, pero la información real del usuario está en otro lugar.
  • Servidor web: El empleado B tiene acceso. Obtiene la información de inicio de sesión, pasa al servidor de autenticación, recupera el hash y luego elimina la información de inicio de sesión. Mantiene el hash en sesión para escribir/consultar en la base de datos.

So Employee A tiene user_id, nombre de usuario, contraseña y algoritmo. El empleado B tiene user_hash y data. A menos que el empleado B modifique el sitio web para almacenar el usuario/contraseña sin formato, no tiene forma de vincularse con los usuarios reales.

Utilizando perfiles de SQL, el empleado A obtendría hash de user_id, nombre de usuario y contraseña (ya que user_hash se genera posteriormente en el código). El empleado B obtendría user_hash y datos.

+0

Además, si separa las dos tablas en dos servidores de bases de datos diferentes, ahora necesita acceder a 3 elementos: tabla de usuarios, tabla de productos y algoritmo de hashing del lado del servidor/servicio web. Lo más probable es que si pueden acceder a una base de datos tienen acceso a la otra, pero aún es menos riesgoso. –

+0

* Si no necesita conectar datos de diferentes sesiones *, puede usar un user_hash diferente y aleatorio cada vez que inicie sesión. Solo deberá almacenar el hash durante la sesión. Después de eso, no tendrías forma de saber qué user_id fue a qué user_hash. Aún puede vincular los datos escritos en esa sesión para generar informes o lo que necesite. –

+0

El Analizador de SQL derrota todo esto, ya que las consultas mismas lo delatarán. – NotMe

1

Tenga en cuenta que incluso sin almacenar en ningún lugar la información de identificación de la persona, simplemente asociar suficiente información con la misma clave podría permitirle descubrir la identidad de la persona asociada con cierta información. Para un ejemplo simple, puede llamar al club de striptease y preguntar qué cliente manejó un Ferrari. Por esta razón, cuando desidentifica registros médicos (para fines de investigación y otros), debe eliminar cumpleaños de personas mayores de 89 años (porque las personas mayores son lo suficientemente raras que una fecha de nacimiento específica podría indicar una sola persona) y eliminar cualquier codificación geográfica que especifique un área que contenga menos de 20,000 personas. (Ver http://privacy.med.miami.edu/glossary/xd_deidentified_health_info.htm)

AOL descubrió por las malas cuando publicaron los datos de búsqueda que las personas pueden ser identificadas simplemente por saber qué búsquedas están asociadas con una persona anónima. (Ver http://www.fi.muni.cz/kd/events/cikhaj-2007-jan/slides/kumpost.pdf)

0

Parece que estás en el camino correcto con esto, pero eres un poco más pensando que (o simplemente no lo entiende)

escribir una función que construye una nueva cadena basado en la entrada (que será su nombre de usuario u otra cosa que no puede cambiar las horas extras)

Utilice la cadena devuelta como una sal al construir el hash del usuario (de nuevo, usaría el ID de usuario o nombre de usuario como entrada para el generador de hash porque no cambiarán como la contraseña o el correo electrónico de los usuarios)

Asociar todas las acciones de los usuarios wi el usuario hash.

Nadie que solo tenga acceso a la base de datos puede determinar qué significa el hash del usuario. Incluso un intento de fuerza bruta al intentar diferentes combinaciones de semilla y sal terminará siendo inútil porque la sal se determina como una variante del nombre de usuario.

Creo que ha respondido su propia pregunta con su publicación inicial.

+1

Creo que la suposición es que el nombre del usuario y la información personal deben almacenarse en algún lugar de la base de datos también, y la pregunta es cómo mantener esa información y la información 'secreta' por separado. –

Cuestiones relacionadas