¿Es seguro mi método de autenticación de usuario? ¿Estoy reinventando la rueda?

-8

He leído muchos artículos que me recomiendan usar OpenID, incluido el Desbordamiento de pila, para la autenticación. Desafortunadamente no puedo usar OpenID porque mi autenticación no se basa en un correo electrónico, se basa en un nombre de usuario y contraseña.

Actualmente estoy haciendo una autenticación como esta:

  1. El usuario ingresa el nombre de usuario y la contraseña.
  2. Si el inicio de sesión del usuario es exitoso, inserte el agente de usuario, IP y una clave única que yo creo en una base de datos.
  3. Establezca la clave única en una cookie y transmítala al usuario.
  4. Siempre que el usuario haga clic en un enlace (abriendo una página), los tres coincidirán. Si falla alguna coincidencia, se desconectará.

Creo la clave única al cifrar time stamp + ip + useragent + username muchas rondas con MCRYPT_RIJNDAEL_256.

Todas las conexiones se realizan mediante TLS para evitar el rastreo.

¿Este tipo de autenticación es seguro desde el secuestro de sesión, o debo modificar este método?

    
pregunta CS GO 04.03.2014 - 13:49
fuente

4 respuestas

13

¿Sabes lo que no deberías hacer? Reinventa la rueda.

Hay muchas bibliotecas de autenticación, especialmente para PHP. Casi todos los marcos incluyen uno. Úsalo . Si no está utilizando un marco, deje de hacer lo que está haciendo y use uno.

Y sí, debes usar TLS para tu sitio.

    
respondido por el Ayrx 04.03.2014 - 13:57
fuente
2

Nunca debes tirar el tuyo. Existe una llamada "Ley Schneier" que dice:

  

Cualquiera, desde el aficionado más despistado al mejor criptógrafo, puede   crear un algoritmo que él mismo no pueda romper.

Eso significa que incluso después de que no logres romper tu propio esquema, un experto puede romperlo en dos segundos. Eche un vistazo a este artículo de Schneier.

Hay miles de métodos que funcionan y usted debería usarlos, muchos de ellos han sido probados por criptógrafos y profesionales de seguridad.

Además, deberías leer esta Q & A.

    
respondido por el kiBytes 04.03.2014 - 14:39
fuente
2
  

No puedo usar openid porque mi autenticación no se basa en la identificación del correo electrónico

OpenID no depende del correo electrónico, una identidad de OpenID podría ser algo así como someone.example.com .

  

Luego inserte (usuario, ip, clave única que creo). en una base de datos.

No es aconsejable vincular sus sesiones a la dirección IP. Las direcciones IP de algunos usuarios variarán legítimamente (por ejemplo, porque están detrás de un clúster proxy o están cambiando entre redes móviles). Ponerlos en marcha al cambio de IP haría que su sitio sea muy difícil de usar para un subconjunto de su audiencia.

La concordancia de IP es, en cualquier caso, de utilidad muy limitada. El ataque habitual que intenta abordar es el de la fuga de token de sesión y la reutilización de un cliente atacante. Pero las posibles causas de la fuga de tokens son generalmente aquellas que le dan al atacante acceso para hacer solicitudes del cliente de todos modos (XSS, malware del lado del cliente, seguridad de transporte defectuosa) o aquellas que ya son catastróficas (compromiso de la base de datos, ejecución del código del servidor). p>

De forma similar, la concordancia Usuario-Agente es de poco valor, ya que la cadena UA no es ningún tipo de secreto y es fácil de falsificar. La concordancia de IP y UA puede valer como una entrada para un sistema de clasificación de riesgo complejo con historial de comportamiento, pero la conciliación primitiva es ineficaz como medida de seguridad y es probable que cause más daños por falsos negativos que beneficios.

  

Marca de tiempo + ip + agente de usuario + nombre de usuario y cifrándolos muchas rondas = clave única!

     

Tipo de cifrado = MCRYPT_RIJNDAEL_256

     

Luego inserte (usuario, ip, clave única que creo). en una base de datos.

     

configura la clave única en la cookie y la transmite al usuario.

Como la 'clave única' enviada por el cliente se verifica simplemente comparándola con el valor conocido en la base de datos, su contenido real no es relevante y no tiene sentido generarla de una forma tan elaborada.

Una cadena de datos aleatorios haría lo mismo para esto, y luego lo que tendrías sería equivalente funcionalmente a la forma normal en que la gente hace inicios de sesión en PHP: colocando un ID de usuario registrado en la sesión . Reutilizar las sesiones estándar basadas en PHPSESSID aleatorias de PHP tendría ventajas en términos de rendimiento y la naturaleza bien entendida de su configuración.

Hay otro modelo de autenticación algo común, que puede ser lo que pensabas con la idea de "clave única". Aquí es donde crea un token basado en los elementos que desea autenticar (generalmente, ID de usuario, números de generación de contraseña / restablecimiento y tiempo de caducidad del token) junto con una firma criptográfica sobre esos elementos (normalmente HMAC) usando una clave secreta del lado del servidor. El servidor puede reconocer y autenticar el token entrante utilizando esa firma, lo que le da la ventaja de que no necesita ningún almacenamiento de sesión / base de datos persistente. Pero a menos que necesite esa propiedad en particular, me quedaría con las sesiones antiguas.

  

Creo que usar TLS es obligatorio aquí

Sí. Y recuerde dar a sus cookies la marca secure para que no se filtren a través de una solicitud que no sea TLS.

    
respondido por el bobince 04.03.2014 - 15:22
fuente
0

Las respuestas anteriores que sugieren no reinventar la rueda de autenticación faltan por completo en el punto en el que estás creando un token de autenticación. La mejor rueda para los tokens de autorización creo que sería usar algo como HMAC + SHA2.

Minor nit, no use la marca de tiempo de la creación, sino el momento en que el token caducará. Y si es posible, no use el inicio de sesión a menos que realmente lo necesite. El principio de privilegio mínimo debe aplicarse, por lo que para crear un token de autorización para un servicio REST de lógica empresarial que no necesita un nombre de usuario, no lo suministre ni lo incluya en la generación del token de autenticación.

Así que terminarás con algo como:

authkey = base64 (hmac (sha224, concat (expiretime, ip, useragent), secretkey))

    
respondido por el user1703394 08.03.2014 - 13:39
fuente

Lea otras preguntas en las etiquetas