Crypto asimétrico: descifrar mensajes propios sin tener clave privada

3

He construido un sistema de mensajes para mi sitio web. Los usuarios pueden enviar los mensajes de administrador que se almacenan en la base de datos después de haber sido cifrados AES.

Creo que el uso de criptografía asimétrica (RSA a través de openssl) sería más seguro: no hay clave de descifrado al código en la fuente php. De hecho, solo el administrador tendrá la clave privada.

Los problemas comienzan cuando creo la función de carpeta enviada en PHP. ¿Cómo pueden los usuarios descifrar sus propios mensajes enviados si no tienen la clave de administración privada?

EDITAR! Por favor, dígame si este enfoque es válido y más seguro que las claves simétricas codificadas en PHP:

1) el script genera un par de claves de usuario de su contraseña (ingresada manualmente)

2) openssl_seal cifra el mensaje mediante claves públicas (clave de pub generada por el administrador estándar y clave de pub derivada de la contraseña del usuario).

3) el script almacena los resultados en la base de datos.

4) cuando el usuario solicita el contenido, el script deriva el par de claves del usuario y lo descifra.

5) cuando el administrador solicita la secuencia de comandos de contenido utiliza la clave de administrador estándar y se descifra.

    
pregunta Surfer on the fall 15.08.2012 - 12:13
fuente

4 respuestas

2

OpenPGP

La forma estándar de manejar esto es almacenar los mensajes cifrados en formato estándar OpenPGP . ¿Hay alguna razón para no usar alguna biblioteca comercial que implemente RFC 4880 y RFC 3156 ?

(Hay mucha discusión práctica sobre OpenPGP en este sitio de Seguridad de TI y una discusión más teórica de OpenPGP en el sitio Cryptography StackExchange ).

El mensaje cifrado en formato OpenPGP se puede almacenar como un archivo, un BLOB de SQL, etc.

details

OpenPGP funciona exactamente como se explica fin1te (por lo que puedo decir, openssl_seal () también funciona exactamente de la misma manera):

  • Para cada mensaje, el sistema genera una clave de sesión nueva, nueva y aleatoria que nadie más podría adivinar. Después de almacenar el mensaje cifrado completo BLOB, el sistema olvida esa clave inmediatamente.
  • El texto sin formato del mensaje se cifra con esa clave de sesión y se almacena en el paquete de datos cifrados simétricamente dentro del BLOB.
  • Varios paquetes de claves de sesión encriptadas se almacenan dentro del BLOB; cada una contiene otra copia idéntica de la clave de sesión para este mensaje, cada una encriptada con una clave pública diferente. En este caso, una copia se cifra con la clave pública del remitente, y otra copia se cifra con la clave pública del administrador.

Cuando alguien (el usuario o el administrador del sistema) desea leer un mensaje cifrado, esa persona entrega el mensaje cifrado y su frase de contraseña a una pieza de software que lo descifra y le muestra el texto en claro. Ese software normalmente:

  • alimenta la frase de contraseña en una función de derivación de clave. El software utiliza la clave resultante para descifrar un archivo de conjunto de claves para obtener la clave privada de ese usuario y su correspondiente clave pública. (Alternativamente, supongo que uno podría usar una función de derivación de clave para generar una clave privada a partir de una frase de contraseña , luego generar la clave pública a partir de esa clave privada).
  • busca todos los paquetes de clave de sesión encriptados dentro del BLOB hasta que encuentre uno con una clave pública que coincida.
  • Utiliza la clave privada para descifrar la clave de sesión. Luego usa la clave de sesión para descifrar el mensaje de texto simple.

Mientras evite enviar la contraseña a través de HTTP u otros protocolos de texto simple, Esto parece seguro contra ataques pasivos (ver lo que pasa por el cable; leer las cintas de respaldo del servidor, incluidas todas las claves públicas y el anillo de claves cifrado del administrador).

EDITAR:

  

¿Dónde debo guardar el par de llaves cifradas?

Esa es una excelente pregunta, digna de una página de preguntas / respuestas completamente nueva.

En un mundo ideal, le darías a cada usuario un token de seguridad que, cuando se activó por primera vez, generó un nuevo par de llaves y te dio la clave pública, pero la clave privada nunca dejaría el token.

En nuestro mundo menos que ideal, muchas personas usan Gnome Keyring o algún software similar para almacenar el par de llaves cifradas en su computadora portátil o teléfono inteligente personal, como se explica en "formatos estándar de almacenamiento de claves privadas?" .

Sospecho que preferiría un sistema donde no tenga que comprar un montón de tokens de seguridad, y donde sus usuarios aún puedan acceder a sus propios archivos en su servidor, incluso si su teléfono inteligente se perdió accidentalmente o fue bloqueado o destruido de alguna manera. Otra manera. Eso te obliga a almacenar un conjunto de claves cifradas en el servidor. "¿Este diseño de cifrado del lado del cliente es seguro?" discute algunas de las implicaciones.

    
respondido por el David Cary 15.08.2012 - 23:58
fuente
6

Si encripta el mensaje con un algoritmo simétrico (AES), almacena esta clave dos veces: una vez encriptada con la clave pública del administrador y la otra con la clave pública del usuario.

De esta manera, cuando el administrador quiere ver el mensaje, descifra la primera clave y el usuario usa la segunda.

    
respondido por el fin1te 15.08.2012 - 12:32
fuente
3

Creo que la mejor pregunta es: "¿Qué problema intentas resolver con este cifrado?"

En la práctica, la criptografía de clave pública se usa en canales inseguros para garantizar tanto la integridad de los datos como el no repudio (el mensaje está intacto, sin cambios, y proviene de quién se dice que proviene). Posiblemente, la única razón por la que puedo pensar que estarías cifrando la información antes de que ingresara en la base de datos es porque la base de datos en sí es el medio inseguro, por lo que diría que asegure el medio antes de que usted lo haga los datos.

Aunque si tiene la intención absoluta de proteger esta información con una clave pública, entonces tomaría un enfoque similar al que surgió con @ fin1te. Cifre el mensaje en dos lugares, una vez (en la bandeja de entrada del administrador) utilizando la clave pública del administrador, de manera que solo el administrador pueda leerlo; y una segunda vez (en la casilla Enviados por el usuario) de forma simétrica utilizando la contraseña del Usuario como clave AES (o permitiendo que el usuario elija una contraseña de cifrado separada). De esa manera, el usuario todavía tiene acceso y se asegura de que solo el administrador tenga acceso a los que se le envían.

La única advertencia que tengo en cuenta es que si el usuario cambia la contraseña, deberá revisar todos los mensajes enviados y volver a cifrarlos con la nueva contraseña.

EDITAR: No veo ningún defecto matemático en su algoritmo propuesto que no se haya hablado en la pregunta referenciada , una cosa a tener en cuenta es que PHP OpenSSL_Seal genera una clave simétrica aleatoria y cifra eso utilizando los pares de claves públicas proporcionados. Tendrá que almacenar esa clave en la base de datos para poder revertir el proceso.

Su proceso inverso se vería así:

  1. El usuario proporciona una contraseña expandida como semilla para PRNG
  2. Use PRNG para "sembrar" el esquema de generación de claves para recuperar claves privadas
  3. Descifre la clave simétrica almacenada utilizando una clave privada derivada
  4. Descifra los mensajes usando una clave asimétrica descifrada.

En general, parece mucho trabajo y un costo computacional si lo haces en cada actualización de página , solo para leer algunos mensajes enviados.

Ya que openssl_seal usa claves simétricas de todos modos, ¿por qué no solo cortocircuitar eso y usar la contraseña del usuario?

    
respondido por el Sean Madden 15.08.2012 - 15:01
fuente
2

Supongo que está haciendo lo que @Sean Madden describe en los pasos anteriores, que hay dos copias de los datos almacenados: 1 copia cifrada con la clave privada del administrador y 1 copia cifrada con la clave privada del usuario generada a partir de Su contraseña de cifrado.

Sí, eso debería funcionar.

En términos de comparación, las compensaciones serían:

  • no almacena el secreto crítico (la clave privada) en el sistema operativo de esta manera. Si la piratería de la memoria persistente es su gran preocupación, entonces esto lo soluciona.

  • con el cifrado asimétrico, es probable que esté agregando un factor de tiempo al descifrado, tanto para el administrador como para el usuario. El cifrado / descifrado asimétrico es un costo de CPU más alto que el simétrico y puede tener mucho que ver con qué tan bien se implementa su motor. Espere algunos problemas de crecimiento aquí: dónde y cómo realiza el cálculo tendrá un gran impacto en la satisfacción del usuario.

  • de cualquier manera, sin hardware sofisticado, sus claves privadas serán manejadas por el sistema operativo durante el proceso de encriptación. Se vuelve más difícil de piratear cuando no están almacenados en un archivo en algún lugar del sistema operativo, pero nada es imposible, esto depende en gran medida de la naturaleza de la amenaza contra la que intenta protegerse.

  • ¿Qué tan seguro está de que los usuarios pueden recordar sus contraseñas de una manera compatible con la seguridad? Si están grabando contraseñas en sus pantallas, usted tiene otro tipo de riesgo. Con el sistema que describe, un usuario pierde el acceso a todos los correos enviados en su carpeta si olvida su contraseña. Si le ofrece un mecanismo de recuperación de contraseñas, entonces tiene que protegerlo más fuertemente de lo que protegió las claves simétricas originales. Cada vez que agregas secretos de seguridad en un lugar, creas un objetivo de valor más alto para los atacantes y debes protegerlo en consecuencia.

respondido por el bethlakshmi 15.08.2012 - 15:38
fuente

Lea otras preguntas en las etiquetas