Cifrar datos confidenciales en software y almacenarlos / descifrarlos en un servidor

8

He buscado en IT Security y Google algo similar a esto, pero no pude encontrar nada relacionado de forma remota con lo que estoy haciendo.

Estoy desarrollando un software que consta de 2 partes: un programa C # que se ejecuta en una sola computadora segura y confiable, y un software PHP que se ejecuta en un servidor. Este sistema se ocupa de datos confidenciales, es decir, registros de farmacias (no en EE. UU., HIPPAA no se aplica).

Quiero cifrar de forma segura los datos, de modo que incluso en el caso de que la base de datos sea robada, se puede descifrar la menor cantidad de datos posible. Ya estoy protegiendo los datos al no almacenar ningún dato identificable como Nombre, Dirección, etc., guardar para una dirección de correo electrónico.

Inicialmente quería usar una variante en esta solución , sin embargo en Además, me di cuenta de que RSA no era una forma adecuada de cifrar el texto plano directamente. Mi investigación me llevó a creer que AES es el algoritmo más apropiado para eso. Sé que el consejo dado a la mayoría de las personas que no son expertos en encriptación es seguir un protocolo estándar de la industria, sin embargo, no pude encontrar uno que coincidiera con mis criterios.

Los criterios son:

  • Para los datos de cada usuario, solo el propio usuario debe poder acceder matemáticamente a sus datos dado el contenido del servidor, lo que significa que se usa una clave derivada de su contraseña (el software C # tiene acceso completo a los datos de todos los usuarios, puede tener acceso a las teclas)
  • No debería ser posible descifrar haber obtenido únicamente los contenidos del servidor
  • Los datos de texto sin formato nunca deben almacenarse en el servidor (por lo tanto, quiero cifrarlos en el software C #)
  • Los datos deben poder cifrarse sin que el usuario esté disponible para proporcionar su contraseña
  • Los datos solo se descifrarán y leerán en PHP; no será necesario volver a cifrar y escribir datos nuevos o modificados
  • Solo se puede almacenar o acceder a un hash de la contraseña del usuario

Aquí hay una solución que he encontrado:

Naturalmente, todas las conexiones se realizan a través de TLS / SSL (a través de HTTPS). Antes de transferir datos confidenciales, el servidor y el software están "preparados" o emparejados. Se genera un par de claves asimétricas en el servidor y la clave privada se transfiere al software (me refiero al componente C # como "el software"). La clave privada se elimina del servidor y la clave pública se almacena.

Cuando un usuario se registra, su contraseña se usa para generar una clave de 128 bits utilizando PBKDF2. Esta clave está cifrada por RSA utilizando la clave pública generada anteriormente y almacenada.

Cuando los datos se cargan desde el software al servidor (cada 24 horas), el software envía una lista de los identificadores de usuario para los cuales se cargarán los datos (a través de HTTPS, por supuesto). El servidor devuelve una lista de las claves de 128 bits cifradas por RSA junto con los identificadores de usuario correspondientes. El software los descifra uno por uno utilizando su clave privada, obteniendo una lista de claves de 128 bits. Para cada usuario, el servidor toma los datos de ese usuario y los cifra con AES-128 usando la clave correspondiente de ese usuario. Toda la carga útil se carga en el servidor y se almacena directamente.

Cuando un usuario inicia sesión, se puede acceder a su contraseña por poco tiempo y se utiliza PBKDF2 para generar su clave AES-128. Para evitar que tengan que volver a ingresar su contraseña en cada carga de página, la clave AES-128 se almacena en una cookie segura en su máquina con un tiempo de caducidad corto (5-10min) y se usa en las cargas de página subsiguientes para descifrar y mostrar Los datos de ese usuario. No se almacena realmente en el servidor en ningún momento.

¿Este protocolo de seguridad es apropiado? ¿Debo modificarlo? ¿Hay algo que sea estándar en la industria y funcionaría aquí? Cualquier ayuda sería apreciada grandemente.

    
pregunta Matt Jadczak 28.02.2013 - 00:18
fuente

1 respuesta

5

Desplegar tu propio protocolo es difícil . Fácilmente tendrá algo que se ejecuta más o menos, pero obtener algo que también sea seguro requerirá mucho trabajo y también una cantidad significativa de suerte.

A partir de sus requisitos, le gustaría un protocolo similar al siguiente:

  • Cada usuario tiene un par de claves asimétricas, adecuadas para el cifrado (por ejemplo, RSA o ElGamal).
  • La clave privada Kpriv se cifra con una clave simétrica K derivada de la contraseña del usuario y luego se almacena en el servidor.
  • La clave pública Kpub se almacena en el servidor sin cifrado (es pública ).
  • Los elementos de datos se cifran con Kpub . Cualquiera puede cifrar cualquier cosa con una clave pública (ese es el punto en el que la clave pública es pública).
  • Para descifrar los datos, el usuario escribe su contraseña, que se usa para volver a calcular K , y luego descifra el blob que contiene Kpriv . Con esa clave privada asimétrica, el usuario puede descifrar todos los archivos de datos que se han cifrado con la clave pública correspondiente.

El formato OpenPGP contiene todas las primitivas necesarias para eso. BouncyCastle es una biblioteca de código abierto que puede usar ese formato, y es una versión de C # / .NET.

    
respondido por el Thomas Pornin 28.02.2013 - 18:00
fuente

Lea otras preguntas en las etiquetas