una servicios seguridad segura que por parte net generar encriptado construyendo con como basada autenticacion acceso security rest authentication token

security - servicios - Implementación del token de autenticación del servicio web REST



seguridad servicios rest java (1)

Estoy implementando un servicio web REST usando C # que se alojará en Azure como un servicio en la nube. Como es un servicio REST, no tiene estado y, por lo tanto, no tiene cookies ni estados de sesión.

Solo se puede acceder al servicio web a través de HTTPS (certificado proporcionado por StartSSL.com).

Cuando un usuario inicie sesión con éxito en el servicio, recibirá un token de seguridad. Este token proporcionará autenticación en futuras comunicaciones.

El token contendrá una marca de tiempo, ID de usuario e IP del cliente.

Toda la comunicación solo se realizará a través de HTTPS, por lo que no me preocupa que el token sea interceptado y utilizado en los ataques de repetición; el token tendrá un vencimiento de todos modos.

Dado que se trata de un servicio público, me preocupa que alguien pueda registrarse en el servicio, iniciar sesión y luego modificar el token que recibe para acceder a las cuentas de otros usuarios.

Me pregunto cuál es la mejor forma de proteger el contenido del token y también verificar que no haya sido alterado.

Planeo hacer lo siguiente para asegurar el token:

El cliente inicia sesión correctamente en el servicio y el servicio lo hace:

  1. Genera un valor aleatorio y hash con SHA256 1000 veces.
  2. Genere una clave de sesión única de clave privada + valor aleatorio hash.
  3. Haga clic en la clave de sesión con SHA256 1000 veces y luego úselo para cifrar el token
  4. Use la clave privada para firmar el token cifrado mediante RSA.
  5. Envía el token cifrado + la firma + el valor aleatorio hash al cliente en un paquete JSON sin encriptar.

Cuando el cliente llama a un servicio, envía el token cifrado y la firma en un paquete JSON no encriptado al servicio. El servicio será

  1. Vuelva a crear la clave de sesión desde la clave privada + el valor aleatorio hash
  2. Use la clave privada para verificar la firma
  3. Utilice la clave de sesión hash para descifrar el token
  4. Verifica que el token no haya expirado
  5. Continuar con la operación solicitada ...

Realmente no sé nada sobre el cifrado, así que tengo algunas preguntas:

  1. ¿Es esto suficiente o es excesivo?
  2. Leí que para detectar alteraciones debería incluir un HMAC con el token. Como firmo con la clave privada, ¿todavía necesito un HMAC?
  3. ¿Debo usar Rijndael en lugar de RSA?
  4. Si se prefiere Rijndael, ¿se necesita descifrar el IV generado? es decir, ¿puedo tirarlo o necesito enviarlo? ¿El token encriptado? por ejemplo, cifrado Token + HMAC + IV + valor aleatorio hash.

Dado que todas las comunicaciones se realizan a través de HTTPS, el paquete JSON sin encriptar no está realmente descifrado hasta que llega al cliente.

También es posible que desee volver a implementar el servicio en PHP más tarde, por lo que todo esto también debe ser factible en PHP.

Gracias por tu ayuda


Estás realmente pensando demasiado en el token. A decir verdad, la mejor seguridad de token se basa en la aleatoriedad o, más exactamente, en la imprevisibilidad . Los mejores tokens son completamente aleatorios. Tiene razón en que una preocupación es que un usuario modifique su token y lo use para acceder a las cuentas de otros. Este es un ataque común conocido como "robo de sesión". Este ataque es casi imposible cuando los tokens se generan aleatoriamente y caducan en el lado del servidor. Usar la información del usuario como IP y / o una marca de tiempo es una mala práctica porque mejora la predictibilidad. Hice un ataque en la universidad que adivinaba con éxito tokens activos que se basaban en las marcas de tiempo del servidor en microsegundos. El autor de la aplicación pensó que los microsegundos cambiarían lo suficientemente rápido como para ser impredecibles, pero ese no era el caso.

Debe tener en cuenta que cuando los usuarios están detrás de los servidores proxy, el proxy algunas veces verá sus solicitudes SSL en texto plano (por razones de seguridad, muchos proxies realizarán una profunda inspección de paquetes). Por esta razón, es bueno que expire las sesiones. Si no lo hicieras, tus usuarios serían vulnerables a un ataque como este, y también posible XSS y CSRF.

RSA o Rijndael deberían ser suficientes, siempre que tengan una longitud de clave razonable. Además, debe usar un HMAC con el token para evitar manipulaciones, incluso si lo está firmando. En teoría, sería redundante, ya que estás firmando con una clave privada. Sin embargo, HMAC está muy bien probado y su implementación del mecanismo de firma podría ser defectuosa. Por esa razón, es mejor usar HMAC. Se sorprendería de la cantidad de implementaciones de seguridad "roll your own" que tienen fallas que las llevan a un compromiso.

Suena bastante inteligente en seguridad. Sigan con el buen trabajo! Necesitamos más desarrolladores conscientes de la seguridad en este mundo.

EDITAR:

Se considera seguro incluir marcas de tiempo / ID de usuario en el token, siempre que estén cifradas con una clave secreta simétrica fuerte (como AES, Blowfish, etc.) que solo tiene el servidor y siempre que el token incluya un hash inviolable con él, como HMAC, que se cifra con la clave secreta junto con la identificación de usuario / marca de tiempo . El hash garantiza la integridad y el cifrado garantiza la confidencialidad.

Si no incluye el HMAC (u otro hash) en el cifrado, es posible que los usuarios alteren el token cifrado y lo descifren a algo válido. Hice un ataque en un servidor en el que la identificación del usuario y la marca de tiempo se encriptaron y se usaron como un token sin un hash. Al cambiar un carácter al azar en la cadena, pude cambiar mi ID de usuario de algo así como 58762 a 58531. Si bien no pude elegir la "nueva" identificación de usuario, pude acceder a la cuenta de otra persona (esto fue en el mundo académico , como parte de un curso).

Una alternativa a esto es usar un valor de token completamente aleatorio y asignarlo en el lado del servidor a la identificación de usuario / indicación de tiempo almacenada (que permanece en el lado del servidor y por lo tanto está fuera del control del cliente). Esto requiere un poco más de memoria y poder de procesamiento, pero es más seguro. Esta es una decisión que deberá tomar caso por caso.

En cuanto a la reutilización / derivación de claves de la IV y otras claves, esto generalmente está bien, siempre que las claves solo sean válidas durante un corto período de tiempo. Matemáticamente, es poco probable que alguien pueda romperlos. Sin embargo es posible. Si quieres ir a la ruta paranoide (que normalmente hago), genera todas las nuevas claves al azar.