Me gustaría algún comentario sobre la siguiente idea de autenticación, ¿tiene sentido, y hay un estándar forma de hacer esto (o similar) para que pueda confiar en una implementación bien probada.
He visto muchas respuestas aquí sobre cómo asegurar la comunicación al servidor, y la mayoría de las respuestas son simplemente utilizar TLS correctamente. Estoy buscando una solución que permita encriptar y firmar los mensajes, para que el mensaje permanezca a salvo al pasar por el backend, hasta que lleguen al servicio de destino.
Context
- Aplicación móvil para Android 2.3+ y iOS 6+ creada con phonegap (por lo tanto, las libs usadas deben poder utilizarse desde Java / obj-c o js)
- La aplicación se comunica con el servidor mediante una API REST json
- El contenido del mensaje debe permanecer confidencial a medida que pasa por el backend (sin terminación en el proxy / equilibrador de carga)
- Debería ser compatible con "recordarme", para que el usuario no tenga que volver a ingresar su contraseña todo el tiempo
- Todas las comunicaciones se realizan a través de ssl / tls
Autenticación
- el cliente recopila las credenciales del usuario (nombre de usuario, frase de contraseña y alguna información de seguridad adicional)
- el cliente genera una clave simétrica
- el cliente cifra las credenciales con la clave simétrica
- el cliente cifra la clave simétrica con la clave pública del servidor (enviada con el cliente)
- el cliente envía el mensaje cifrado, la clave y el nonce a través de https (validando el certificado del servidor)
- el proxy del servidor reenvía la solicitud de autenticación al servicio de autenticación
- el servicio de autenticación descifra la clave y el mensaje simétricos
- si las credenciales son válidas, el servicio genera un token de autenticación
- el token está asociado a la clave simétrica en el servidor, si las credenciales no son válidas, la clave se descarta después de responder a la solicitud
- el token se devuelve al usuario, cifrado con la clave simétrica
- el token y la clave se almacenan localmente en el cliente, cifrados por una contraseña corta
Supongo que estas solicitudes están a salvo de los ataques de reproducción si se usa tls, por lo que no hay riesgo de que un atacante reproduzca el mensaje para obtener un token nuevo.
Otras llamadas a la API
- el cliente genera los mensajes de solicitud, los cifra y firma el mensaje cifrado
- el cliente envía el mensaje cifrado, el nonce y la firma con su token de autenticación al servidor
- en la recepción, el servidor busca la clave asociada con el token recibido, verifica la firma y descifra el mensaje antes de procesarlo
Preguntas
- ¿Hay algún problema con la reutilización de la misma clave simétrica?
- ¿Qué es una buena elección de clave simétrica?
- ¿Qué pasa con la firma AES-OCB o AES-CBC + HMAC?
- ¿con qué frecuencia se debe cambiar la clave simétrica?
- ¿Cuál es la mejor manera de actualizar las claves / actualizar tokens? Estaba pensando en emitir un token de actualización durante La respuesta de autenticación y las claves caducan después de un período específico, por lo que si el usuario no actualiza su Clave que tienen que iniciar sesión de nuevo.
Gracias