returns remarks recuperar para generate example enviar correo contraseña c# asp.net asp.net-mvc security

c# - remarks - ¿Cómo implementar los restablecimientos de contraseña?



remarks c# (6)

1) Para generar el ID único, puede usar el Algoritmo Secure Hash. 2) temporizador adjunto? ¿Quiso decir un vencimiento para el enlace restablecer pwd? Sí, puede tener un juego de Caducidad 3) Puede solicitar más información que no sea el Id. De correo electrónico para validarlo. Al igual que la fecha de nacimiento o algunas preguntas de seguridad 4) También puede generar caracteres aleatorios y solicitar ingresar también junto con la solicitud .. para asegurarse de que la solicitud de contraseña no esté automatizada por algunos programas espía o cosas por el estilo ...

Estoy trabajando en una aplicación en ASP.NET, y me preguntaba específicamente cómo podría implementar una función Password Reset si quería hacer mi propia versión.

Específicamente, tengo las siguientes preguntas:

  • ¿Cuál es una buena forma de generar una identificación única que es difícil de descifrar?
  • ¿Debería haber un temporizador adjunto? Si es así, ¿cuánto tiempo debería ser?
  • ¿Debo registrar la dirección IP? ¿Incluso importa?
  • ¿Qué información debo solicitar en la pantalla "Restablecer contraseña"? ¿Solo dirección de correo electrónico? ¿O tal vez la dirección de correo electrónico más alguna información que "saben"? (Equipo favorito, nombre del cachorro, etc.)

¿Hay alguna otra consideración que deba tener en cuenta?

NB : Otras preguntas han pasado por alto completamente la implementación técnica. De hecho, la respuesta aceptada pasa por alto los detalles sangrientos. Espero que esta pregunta y las respuestas posteriores entren en los detalles sangrientos, y espero al formular esta pregunta de forma mucho más restringida que las respuestas sean menos ''peludas'' y más ''sangrientas''.

Editar : También se agradecerán las respuestas que también incluyan cómo se modelará y manejará una tabla en SQL Server o cualquier enlace ASP.NET MVC a una respuesta.


EDITAR 22/05/2012: Como seguimiento de esta popular respuesta, ya no uso GUID en este procedimiento. Al igual que la otra respuesta popular, ahora uso mi propio algoritmo hash para generar la clave para enviar la URL. Esto tiene la ventaja de ser más corto también. Mire en System.Security.Cryptography para generarlos, que usualmente también uso SALT.

Primero, no restablezca inmediatamente la contraseña del usuario.

Primero, no restablezca inmediatamente la contraseña del usuario cuando lo solicite. Esta es una violación de seguridad ya que alguien podría adivinar las direcciones de correo electrónico (es decir, su dirección de correo electrónico en la empresa) y restablecer las contraseñas por capricho. Actualmente, las mejores prácticas suelen incluir un enlace de "confirmación" enviado a la dirección de correo electrónico del usuario, que confirma que desea restablecerlo. Este enlace es el lugar donde desea enviar el enlace clave único. Envío el mío con un enlace como: domain.com/User/PasswordReset/xjdk2ms92

Sí, establezca un tiempo de espera en el enlace y almacene la clave y el tiempo de espera en su back-end (y sal si está usando uno). Los tiempos de espera de 3 días son la norma, y ​​asegúrese de notificar al usuario de 3 días en el nivel web cuando soliciten restablecer.

Use una clave hash única

Mi respuesta anterior dice que use un GUID. Ahora estoy editando esto para aconsejar a todos que usen un hash generado aleatoriamente, por ejemplo, usando el RNGCryptoServiceProvider . Y, asegúrese de eliminar cualquier "palabra real" del hash. Recuerdo una llamada telefónica especial a las 6:00 de la mañana en la que una mujer recibía una cierta "c" en su clave de hash "supuestamente aleatoria" que hacía un desarrollador. Doh!

Procedimiento completo

  • El usuario hace clic en "restablecer" la contraseña.
  • Al usuario se le pide un correo electrónico.
  • El usuario ingresa el correo electrónico y hace clic en enviar. No confirme ni niegue el correo electrónico, ya que esto también es una mala práctica. Simplemente diga: "Hemos enviado una solicitud de restablecimiento de contraseña si el correo electrónico está verificado". o algo críptico por igual.
  • Usted crea un hash del RNGCryptoServiceProvider , lo almacena como una entidad separada en una tabla ut_UserPasswordRequests y el enlace vuelve al usuario. De modo que puede seguir las solicitudes antiguas e informar al usuario que los enlaces más antiguos han caducado.
  • Envía el enlace al correo electrónico.

El usuario obtiene el enlace, como http://domain.com/User/PasswordReset/xjdk2ms92 , y hace clic en él.

Si se verifica el enlace, solicite una nueva contraseña. Simple, y el usuario puede establecer su propia contraseña. O bien, configure su propia contraseña críptica aquí e infórmeles de su nueva contraseña aquí (y envíela por correo electrónico).


Es probable que un GUID enviado a la dirección de correo electrónico registrada sea suficiente para la mayoría de las aplicaciones comunes y corrientes, con un tiempo de espera aún mejor.

Después de todo, si el buzón de correo electrónico de los usuarios se ha visto comprometido (es decir, un hacker tiene el inicio de sesión / contraseña de la dirección de correo electrónico), no hay mucho que pueda hacer al respecto.


Muchas buenas respuestas aquí, no me molestaré en repetirlo todo ...

Excepto por un problema, que se repite en casi todas las respuestas aquí, aunque sea incorrecto:

Las guías son (de manera realista) únicas y estadísticamente imposibles de adivinar

Esto no es cierto, los GUID son identificadores muy débiles y NO se deben usar para permitir el acceso a la cuenta de un usuario.
Si examina la estructura, obtendrá un total de 128 bits como máximo ... lo cual no se considera mucho hoy en día.
De los cuales la primera mitad es invariante típica (para el sistema generador), y la mitad de lo que queda es dependiente del tiempo (o algo similar).
Con todo, es un mecanismo muy débil y fácilmente reforzado.

¡Así que no uses eso!

En su lugar, simplemente use un generador de números aleatorios criptográficamente fuerte (System.Security.Cryptography.RNGCryptoServiceProvider) y obtenga al menos 256 bits de entropía sin formato.

Todo lo demás, como las numerosas otras respuestas proporcionadas.


Primero, necesitamos saber lo que ya sabes sobre el usuario. Obviamente, tienes un nombre de usuario y una contraseña anterior. ¿Qué más sabes? ¿Tienes dirección de correo electrónico? ¿Tiene datos sobre la flor favorita del usuario?

Suponiendo que tiene un nombre de usuario, una contraseña y una dirección de correo electrónico funcional, debe agregar dos campos a su tabla de usuarios (suponiendo que sea una tabla de base de datos): una fecha llamada new_passwd_expire y una cadena new_passwd_id.

Suponiendo que tiene la dirección de correo electrónico del usuario, cuando alguien solicita un restablecimiento de contraseña, actualice la tabla de usuario de la siguiente manera:

new_passwd_expire = now() + some number of days new_passwd_id = some random string of characters (see below)

A continuación, envíe un correo electrónico al usuario a esa dirección:

Querido tal y tal

Alguien ha solicitado una nueva contraseña para la cuenta de usuario <nombre de usuario> en <su nombre de sitio web>. Si solicitó este restablecimiento de contraseña, siga este enlace:

http://example.com/yourscript.lang?update=<new_password_id < http://example.com/yourscript.lang?update=<new_password_id >

Si ese enlace no funciona, puede ir a http://example.com/yourscript.lang e ingresar lo siguiente en el formulario: <new_password_id>

Si no solicitó restablecer la contraseña, puede ignorar este correo electrónico.

Gracias, yada yada

Ahora, codificando yourscript.lang: Este script necesita una forma. Si la actualización var pasó en la URL, el formulario solo solicita el nombre de usuario y la dirección de correo electrónico del usuario. Si la actualización no se aprueba, solicita el nombre de usuario, la dirección de correo electrónico y el código de identificación enviado en el correo electrónico. También pides una nueva contraseña (dos veces, por supuesto).

Para verificar la nueva contraseña del usuario, verifica que el nombre de usuario, la dirección de correo electrónico y el código de identificación coincidan, que la solicitud no haya caducado y que coincidan las dos nuevas contraseñas. Si tiene éxito, cambie la contraseña del usuario a la nueva contraseña y borre los campos de restablecimiento de contraseña de la tabla de usuario. También asegúrese de cerrar la sesión del usuario / borrar todas las cookies relacionadas con el inicio de sesión y redirigir al usuario a la página de inicio de sesión.

Básicamente, el campo new_passwd_id es una contraseña que solo funciona en la página de restablecimiento de contraseña.

Una posible mejora: puede eliminar <username> del correo electrónico. "Alguien ha solicitado un restablecimiento de contraseña para una cuenta en esta dirección de correo electrónico ...". De este modo, al hacer que el nombre de usuario sea algo solo el usuario sabe si el correo electrónico es interceptado. No comencé de esa manera porque si alguien está atacando la cuenta, ya conocen el nombre de usuario. Esta oscuridad añadida detiene los ataques de oportunidad "hombre en el medio" en caso de que alguien malintencionado intercepte el correo electrónico.

En cuanto a tus preguntas:

generando la cadena aleatoria: no necesita ser extremadamente aleatorio. Cualquier generador de GUID o incluso md5 (concat (salt, current_timestamp ())) es suficiente, donde salt es algo en el registro del usuario como se creó la cuenta de marca de tiempo. Tiene que ser algo que el usuario no puede ver.

temporizador: Sí, necesita esto solo para mantener su base de datos cuerda. No es necesario más de una semana, pero al menos 2 días ya que nunca se sabe cuánto tiempo puede durar un correo electrónico.

Dirección IP: dado que el correo electrónico podría retrasarse por días, la dirección IP solo es útil para el registro, no para la validación. Si desea iniciar sesión, hágalo; de lo contrario, no lo necesita.

Pantalla Restablecer: Ver arriba.

Espero que lo cubra. Buena suerte.


Puede enviar un correo electrónico al usuario con un enlace. Este enlace contendría una cadena difícil de adivinar (como GUID). Del lado del servidor, también almacenarías la misma cadena que enviaste al usuario. Ahora, cuando el usuario presiona el enlace, puede encontrar en su entrada de db una cadena secreta y restablecer su contraseña.