How to create a password reset link?

Asked

Viewed 11,947 times

15

I am developing a site that has user registration area, the password is encrypted to increase security on the site, but when the user forget the password how will it be possible to return his password decrypted?

I’ve looked at several sites where you get a link so you can reset your password. Should that link be saved in the database? How can I create a link just for this? What is the logic?

  • 2

    password reset or password recovery? to reset vc do not need to know your previous password

  • @Math I wrote this way because I didn’t know what the best solution was, I was waiting for guidance if it would be better to recover or reset

6 answers

17


You should not store passwords that can be recovered. Use one-way algorithms like the one implemented by BCrypt (option I use in my projects). This means your password 12345 becomes something like 534df$aa in the bank, and it is not possible to transform 534df$aa back to 12345, just take 12345, apply the salt defined and reach the generated hash.

Regarding password recovery: you have an entity (a table) that stores password reset requests, linked to the user who requested them. A dynamic hash is generated to increase the security of this process. When the user follows the link, he is informed via QueryString the hash, the same is checked at the base and, if the link is found (proving that the link is legitimate), a new password is defined by the user through the appropriate form, displayed by you on this screen.

Never implement features that return the password the user has registered, because storing the password so that it can be recovered is a security failure.

Links used:

  • 3

    It is also recommended that the registration relating to the password reset link, in the database, has an expiration date - and that it be removed after this deadline, or after the password reset. Otherwise, someone who takes over a user’s email account can reset the password at any time from an old email.

  • 1

    Very salutary and pertinent, @Renan. In fact the date is crucial in these cases. By the way, I recommend that the interval in which the hash is valid is only a few hours (2 hours is an extremely relevant deadline). Also, delete the tuple to which the hash belongs, after password reset.

  • It is not necessary to use a database for this. Using some authenticated encryption algorithm, one can encrypt a list with the user’s identifier and the time of the request and send an email to the user with the result of the operation in the query string. When accessing the link, the application decrypts the parameter, checks whether the link term is valid and identifies the user.

  • Just solve a hash to always have access to any account on the system, not just the user’s... Just know (or infer) the Ids of each user

2

These links have tokens for each recovery request and/or password change.

For each password recovery request, you should follow the following flow:

  1. Create a token and store it in the database referencing the user’s account;
  2. Then use this token as a password recovery URL parameter so that when the user accesses, your application knows who it is dealing with;
  3. Finally, make a form for the user to input the new password settings;
  4. Send the new settings to the bank, delete the token and voi there!

Technically, that would be the logic.

And just like a log-in system, a password shall not be decrypted. Instead, run a new. Rainbow Tables sometimes already bother one-way encryption, imagine if you used a Base64 to "encrypt" the base of your passwords.

In the most, decryption and use a secure encryption like Bcrypt.

Some tips:

  1. Make the token expire after a certain time. This will increase the obstacles of a malicious user trying to change someone’s password;
  2. Either you save the token for future references, or discard it after using.
  3. I won’t technically explain what the final URL of a password recovery looks like, but I’ll show you what the URL itself looks like: http://seuapp.com/recuperar/senha?token=123k23p2h3klndi2o3nd.

Obviously, the token encryption is fanciful.

2

Remember Password

Can create a link, where user informs the e-mail and with this email you provide a link to troca de senha, since if the password is encrypted in the bank I believe I do not have a way to reverse the criptografia in the format of string.

Like the e-mail will be in the base de dados and an email belongs to a user, to inform which user should be updated or pick up an ID based on it.

Observing: I do not know your tables and fields, so think that email is your identification.


Try to Exchange Password:

First the user should inform the senha atual, the website checks whether the senha is equal to banco de dados. If they are the same you can allow him to inform nova senha and sua repetição.


Campos:

Current Password: |..........|

New Password: |.............|

Repeat Password: |............|

1

Option 1 (simple)

Generate a random password write it to your database using your encryption script, and send the user this new random password.

If there is an attempt to exchange password for another malicious user, the real user will have to log in with the new password.

Option 2 (medium)

Switch the encryption algorithm to one that can be decrypted. So you can send the user your own password, without major problem. The bad part is that if this user "lost" the email, when sending the password you can reveal to an impostor (remembering that many users use the same password for several different accounts). And if a user has access to your encryption algorithm he can reverse the encryption of your entire bank.

Option 3 (difficult)

Generation of a hash for password exchange. It is not complex but laborious to create a new table to store a random hash that will be sent to the user needing this to reset the password. This option is, say, the most complete, there is no easy way to prevent the theft of an account if the "attacker" has access to the email, but at least the password he will not know. And if a malicious user requests password recovery, the real user can simply ignore the email and continue with the old password.

-1

My opinion I think it is better for you to have a logic to generate a new password for the user, concatenating capital letters and lowercase numbers and special characters and send this new password or to the user’s mobile phone, which in my opinion is very cool, or/and to the personal email, because depending on the encryption you use, there is no reversal to plain text, and if there is also not 100% secure, I in your place would generate a new password and send it to the customer and when the customer logs into the system would ask to make the password exchange, but I wouldn’t make him do that.

I hope it might have helped

-1

First you need to know the type of Hashes you are using.

Because there are One-Way and Two-Way Hashes, if it’s one-way, you can’t decrypt the password:

Single Hand: In this case your system needs to generate a new temporary password, and send this new password to the client with the link to reset this password.

Double Hand: In this case your system can search by e-mail the user decrypt the password and send to his email, however it is not a good practice.

PHP ONE-HAND ENCRYPTION

MD5

<?php
    $string = 'O rato reu a ropa do rei de Roma';
    $codificada = md5($string);
    echo "Resultado da codificação usando md5: " . $codificada;
    // 54cf74d1acdb4037ab956c269b63c8ac
?>

SHA1

<?php
    $string = 'O rato reu a ropa do rei de Roma';
    $codificada = sha1($string);
    echo "Resultado da codificação usando sha1: " . $codificada;
    // b186b709f7cf5a1d98d413379a66e511df8d59a4
?>

PHP DUAL-HAND ENCRYPTION

BASE64

<?php
    $string = 'O rato reu a ropa do rei de Roma';
    $codificada = base64_encode($string);
    echo "Resultado da codificação usando base64: " . $codificada;
    // TyByYXRvIHJldSBhIHJvcGEgZG8gcmVpIGRlIFJvbWE=
    $original = base64_decode($codificada);
    echo "Resultado da decodificação usando base64: " . $original;
    // O rato reu a ropa do rei de Roma
    // Note que $original vai ser idêntica a $string
?>

Here is a Link explaining a little more about the types of encryption in PHP

http://blog.thiagobelem.net/criptografia-no-php-usando-md5-sha1-e-base64/

  • 3

    Not! Base64 is not an encryption. MD5 and SHA1 should be avoided for passwords: they are quickly broken. Use Bcrypt, as Tiago said.

  • Are you sure MD-5 is one-way? http://www.md5decrypt.org/

  • 1

    @Tiagocésaroliveira It’s one-way, but it’s easily broken. 9545d5fe013264ea287bbdbf6d1b1076 (is your name) the site does not think, but using a good GPU any finds it in a short time.

  • @Gustavorodrigues I drew! Thanks for the tip! I always thought it was two-way.

  • @Gustavorodrigues, cryptography is a set of techniques for hiding unauthorized access information. The purpose of cryptography is to transform a set of readable information, such as an e-mail, for example, into a tangle of characters impossible to understand. That is Base64 can and is considered encryption, of course extremely simple. Actually the MD5 is very easy to break. And your suggestion to use Bcrypt is the best option!!!

  • In this concept a lot of things become cryptography, but Base64 was not created to be one, it is just a way to store binary data using ASCII characters. But by the concept, yes, it’s cryptography. (but don’t tell anyone, if someone else shows up wearing this instead of something safer)!

  • 2

    It’s been over two years and only now have I seen the shaving in the comment on Base 64. Base64 is not encryption. And it’s not even meant to be crypto, careful when reading, and mostly divulge misinformation.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.