DEV Community

loading...

[PoC] Partially random passwords: or how to protect users passwords from keyloggers with partially random passwords

Youghourta Benali
Back-end developer (PHP / Laravel)
・3 min read

One of the issues we all face when we login to some online accounts especially on public computers, or on any computer that we do not own, is that there is always a risk to get our passwords stolen especially with keyloggers. If a hacker gets a “copy” of your password, she can log in to your account and do whatever she wants.

enter image description here
As always, using 2 factor authentication can mitigate this issue, since the hacker needs to access your phone as well. But what if using 2FA is not an option, and we want to protect the user even in this case, can we detect,when the hacker tries to login, that it is not the real user but rather somebody who stole her password who is trying to log in?

Partially-Random passwords

One solution for this problem is to use partially-random passwords with a random part that is different each time.
What I mean by that is the following:
let’s assume that my password is 123456789, but when I try to login I will not use this password directly, but rather I’d add some random string to the beginning or to the end (or even in the middle) like this:
564564123456789

and when we receive this password (let’s call it the “raw password”), we will strip away the random part and use the remaining part as a password, and we save a hashed version of this raw password in a used_passwords table. And next time the same user tries to login, we check if this raw password (the real password + the random part) was used before, and we deny access to the account if we find it.
The code will look like this:

public function postLogin(Request $request)
    {
        $data = $request->all();
        $email = $data['email'];
        $rawPassword = $data['password'];
        $user = User::where('email', $email)->first();
        $password = $this->getRealPassword($rawPassword, $user);
        if (Auth::attempt(['email' => $email, 'password' => $password])) {
            if (! $this->usedBefore($user->id, $rawPassword)) {
                $this->saveRawPassword($user->id, $rawPassword);
                return redirect('/home');
            } else {
                Auth::logout();
                return redirect()->route('login')->with('authentication-issue', true)->with('used-password', true);
            }
        } else {
            return redirect()->route('login')->with('authentication-issue', true);
        }
    }
Enter fullscreen mode Exit fullscreen mode

enter image description here

What if the hacker knows exactly which part of the password is random?

This is a valid concern, if our hacker knows that a particular website that implements a partially-random password technique is stripping away the first 6 characters each time, she will just do the same and log in to the victim’s account.

The solution to this problem would be to allow the user to chose herself the length of the random part and its position in the password, and each time we attempt to authenticate a certain user we will use her own “rules” (i.e the position and the length of the random part changes from user to user).

We can even add multiple random parts in the same password, which make extracting the real password from any captured password even harder.

And we can even combine this concept of partially-random password with the concept of password-based roles and action I described in my previous article, to add another layer of security to the accounts by triggering some specific actions if the password is used for the second time.

https://github.com/djug/partially-random-passwords

Discussion (4)

Collapse
jakebman profile image
jakebman

If I (the attacker) already have a user's password with the random characters, I only need N guesses to guess an unused password where N is the total length of the password.

I just try replacing each character in the password with a random character one at a time until one of them changes the random phrase and not the critical password.

Collapse
djug profile image
Youghourta Benali Author

the whole idea is to stop the hacker from the first attempt, and either lock the account or notify the user so she can change her password.

besides, any decent authentication would implement a throttling mechanism, or ban a certain IP from trying to login after a certain number of failed attempts

Collapse
polentino911 profile image
Diego Casella

So why not using 2FA? You said that sometimes 2FA is not an option but, if that's you want to achieve, I would recommend to make the effort to use 2FA, instead of reinventing your own security mechanism (which usually is difficult to get it right).

Furthermore, never forget this: 98% of the time your user will be either lazy or stupid; the remaining 1%, both[0].
Do not put them in charge of their own security, ever.

Beucase I can totally see the following scenario, where your user will say

oh damn, I have a 6 characters long password, and now I have to type 6 (or any custom number) more random chars :(
...
you know what? I'll shorten the password to the minimum length required, then the website will take care of the rest. Problem solved!

which effectively weakens the effectiveness of the user's password, not to mention is not compatible with password managers.

[0] the other 1% use a password manager ;)

Collapse
yechielk profile image
Yechiel Kalmenson

All the attacker has to do is wait for the person to log in twice, then the keylogger will know exactly which characters are the password and which are random noise...