Estoy desarrollando una API REST pero no puedo usar HTTPS sin usar certificados autofirmados . Entiendo que eso podría ser aceptable para algunos, pero no quiero que aparezcan mensajes de seguridad en los navegadores de los clientes.
La información que se pasa a la red no es confidencial, por lo que no me importa la escucha, pero quiero asegurarme de que solo los clientes autorizados puedan realizar solicitudes y evitar los ataques de repetición. Aquí está mi idea:
Un usuario está registrado con la aplicación web que ejecuta el servicio. Quieren registrar un cliente API, pero no son desarrolladores, por lo que descargan una aplicación cliente suministrada (en este caso, un lector de tarjetas IC que usarán con una computadora que puede comunicar los datos leídos de las tarjetas escaneadas al servicio web). sobre la API).
Paso uno : la aplicación cliente API genera un par de claves (por ejemplo, OpenSSL) y envía la clave pública al servidor (esto puede ser un paso de carga manual cuando el usuario registra al cliente con el servidor ). El servidor almacena la clave pública en la base de datos asociada con el usuario y una descripción del cliente (por ejemplo, "Lector de tarjetas IC en PC01").
¿Por qué quiero usar un par de claves (como SSH)? Creo que un secreto compartido es vulnerable a las escuchas ilegales, ya que debe ser transferido a través de la red al menos una vez. Si bien esto podría evitarse ingresando manualmente la clave en el terminal del servidor en lugar de transportarla a través de la red, uno de los objetivos de diseño del sistema es permitir que otros usuarios que no sean yo mismo registren clientes y obtengan un token de acceso API mediante la interfaz web solicitud. En esta circunstancia, un intruso podría interceptar una clave secreta compartida, mientras que un par de llaves generado por el cliente lo evitaría.
Paso dos : al realizar una solicitud, el cliente primero obtiene un nonce del servidor (que lo almacena en una lista o base de datos de nonces y marcas de tiempo emitidas) y luego realiza la solicitud incluyendo el nonce mientras Firmando la solicitud con su clave privada. El servidor verifica que el mensaje es auténtico (fue firmado por el cliente y nadie más) antes de ejecutar la solicitud.
Mi objetivo con este enfoque es garantizar que solo los clientes válidos accedan a la API, al mismo tiempo que evitan los ataques de reproducción. Un atacante debe poder ver el contenido de los mensajes (no es realmente sensible), pero no debe poder modificarlos. Al cliente realmente no le importa si los datos que vienen del servidor son auténticos (porque en este caso el cliente está cambiando el estado del servidor, no al revés).
- ¿Este enfoque cumple con estos objetivos de diseño?
- Y lo previene contra los ataques del hombre en el medio (asumiendo el original El registro del cliente fue con el servidor real y no un falso del atacante)?