Estoy trabajando en un proyecto donde cada usuario tendrá un par de claves RSA público / privado. Los usuarios podrán enviarse mensajes cifrados entre sí utilizando la clave pública de cada usuario de destino para que solo los usuarios de destino puedan leer el mensaje (similar a PHP openssl_seal ). Como queremos que el usuario pueda usar cualquier dispositivo para leer o enviar un mensaje, el par de claves se almacenará en un servidor API y la clave privada se cifrará con la contraseña del usuario .
Cuando un usuario inicia sesión desde un nuevo dispositivo, utilizará su contraseña para descifrar la clave privada. El problema es que, idealmente, el servidor API nunca debería poder descifrar la clave privada del usuario, incluso para autenticar al usuario . Originalmente, solo iba a enviar al cliente la clave privada cifrada y permitir que el cliente la descifre. Si el cliente puede descifrarlo, debe tener la contraseña correcta, pero esto sería vulnerable a los ataques de diccionario sin conexión. Para evitarlo, debo autenticar al usuario antes y les doy la clave privada cifrada.
Podría hacer que el cliente envíe la contraseña al servidor y permita que el servidor intente descifrar la clave utilizando la contraseña o incluso simplemente validar la contraseña contra un hash, pero entonces el servidor tendrá la contraseña temporalmente y podrá descifrarla. La clave privada del usuario. Está bien, pero prefiero encontrar una manera de autenticar al usuario sin que el servidor sepa su contraseña.
En mi caso, el cliente será un servidor web PHP o una aplicación de escritorio o móvil nativa, no un navegador, por lo que tengo acceso a una amplia gama de métodos criptográficos. El único cliente autorizado para realizar la llamada al servidor API para crear una cuenta será el servidor web PHP, y actualmente estoy planeando que cree el par de claves pública / privada y encripte la clave privada con la contraseña del usuario. Luego, enviará esa información al servidor API (también ejecutando PHP) para crear la cuenta. El servidor API almacenará la clave privada cifrada, la clave pública, la información sobre el usuario y cualquier mensaje cifrado, pero no podrá descifrar ninguna de ellas.
No estoy tratando de protegerme contra un ataque MITM aquí. Todas las llamadas a la API se realizarán a través de HTTPS. Mi objetivo es construir la API de tal manera que incluso si el gobierno chino pudiera obtener acceso al servidor de la API, aún no pudieran leer ninguno de los mensajes. El servidor web puede tener la clave privada temporalmente, pero no el servidor API.
¿Cómo puedo permitir que el servidor API autentique al usuario sin ser vulnerable a un ataque de fuerza bruta sin conexión y sin que el servidor API necesite la contraseña del usuario?
No dude en decirme que estoy haciendo algo totalmente incorrecto y sugerir algo completamente diferente.