Compare the combination of the numeric keyboard with the user’s bcrypt

Asked

Viewed 286 times

1

Speak guys, I’m developing a numeric keyboard like the banks, in which the user selects a combination of numbers, but has to make the comparison with the password stored it, in bcrypt. The password is always 6 numeric digits (it’s easier, right ;) )

The keyboard:

<div class="password-keyboard">
<div class="row">
    <div class="col-md-4">
        <button class="btn btn-light btn-block" id="btnNumber_1" onclick="digitaCaracter('1')">1 ou 8</button>
        <input type="hidden" id="btnNumberVal_1" name="btnNumber[]" value="1,8" />
    </div>
    <div class="col-md-4">
        <button class="btn btn-light btn-block" id="btnNumber_2" onclick="digitaCaracter('2')">7 ou 2</button>
        <input type="hidden" id="btnNumberVal_2" name="btnNumber[]" value="7,2" />
    </div>
    <div class="col-md-4">
        <button class="btn btn-light btn-block" id="btnNumber_3" onclick="digitaCaracter('3')">5 ou 4</button>
        <input type="hidden" id="btnNumberVal_3" name="btnNumber[]" value="5,4" />
    </div>
    <div class="col-md-4">
        <button class="btn btn-light btn-block" id="btnNumber_4" onclick="digitaCaracter('4')">3 ou 6</button>
        <input type="hidden" id="btnNumberVal_4" name="btnNumber[]" value="3,6" />
    </div>
    <div class="col-md-4">
        <button class="btn btn-light btn-block" id="btnNumber_5" onclick="digitaCaracter('5')">9 ou 0</button>
        <input type="hidden" id="btnNumberVal_5" name="btnNumber[]" value="9,0" />
    </div>
    <div class="col-md-4">
        <a class="btn btn-light btn-block" onclick="removeCaracter()"><i class="fa fa-arrow-left"></i></a>
    </div>
</div>

Every time you open the keyboard, the digits change:

for (var array=[],i=0;i<=9;++i) array[i]=i;
// http://stackoverflow.com/questions/962802#962890
var tmp, current, top = array.length;
if(top) while(--top) {
    current = Math.floor(Math.random() * (top + 1));
    tmp = array[current];
    array[current] = array[top];
    array[top] = tmp;
}

var nmbArr = array;
for (var i = 0; i<=4; i++) {
    $('#btnNumber_'+(i+1)).html(nmbArr[i*2]+' ou '+nmbArr[(i*2)+1]);
    $('#btnNumberVal_'+(i+1)).val(nmbArr[i*2]+','+nmbArr[(i*2)+1]);
}

The keyboard is working that is a beauty:

O Teclado virtual funcionando

The one being sent is being captured as normal. The "problem" is how I will compare the combinations with the password of the user who is hashing bcrypt

As combinações geradas nos botões

A sequencia dos botões clicados

Does anyone have any idea how I’m gonna validate these combinations? Will I have to check 64 times (2 6)???

2 answers

2

Since you didn’t answer @Andrei Coelho, I managed to do so:

    $arrComb = [];
    foreach ($request->btnNumber as $nr => $val) {
        $arrComb[$nr] = explode(",", $val);
    }

    $senha = $request->senha;

    $max = (1 << strlen($senha));
    $arrAux = [];
    for ($i = 0; $i < $max; $i++) {
        $arrAux[] = str_pad(decbin($i), strlen($senha), '0', STR_PAD_LEFT);
    }

    $combs = [];
    foreach ($arrAux as $vals) {
        $nr = '';
        for ($posDig = 0; $posDig <= strlen($senha) - 1; $posDig++) {
            $idx = $senha[$posDig];
            $nr .= $arrComb[$idx][$vals[$posDig]];
        }
        $combs[] = $nr;
    }

    //verificando as combinações possíveis
    foreach ($combs as $value) {
        if (password_verify($value, $userPassword)) {
            return true;
        }
    }

    return false;

If anyone has any comment or improvement, are welcome

  • I was trying so far with recursiveness. But I couldn’t. It’s really hard.

  • Anyway, congratulations on the code.

2


If the final password is hashed crypt, YES! Because it is impossible to decrypt it to make an analysis of each character. Then you will have to encrypt all possible passwords and validate them.

But you can optimize this validation with SQL.

$senhasPossiveis = array(
    "sajEeYaHYyeSU";
    "saepDgtryRTsw";
    "saQ30SFLolsHo";
    "saIie8xFtO5cg";
    "saIie8xFtO5cg";
    "saepDgtryRTsw";
    "saepDgtryRTsw";
    "saIie8xFtO5cg";
    "saepDgtryRTsw";
    "saIie8xFtO5cg";
);

$sql = "SELECT senha, email FROM usuarios WHERE email = '$email' AND ( ";
foreach($senhasPossiveis as $senha){
    $sql .= "senha = '".$senha."' OR ";
}
$sql .= substr($sql, 0, -3).")";

At the end your query will be like this:

SELECT senha, email FROM usuarios WHERE email = '$email' AND ( 
senha = 'sajEeYaHYyeSU' OR
senha = 'saepDgtryRTsw' OR
senha = 'saIie8xFtO5cg' OR
senha = 'saepDgtryRTsw' OR
senha = 'sajEeYaHYyeSU' OR
senha = 'saIie8xFtO5cg' OR
senha = 'sajEeYaHYyeSU' OR
senha = 'saIie8xFtO5cg')

ALTERNATIVE

This solution is also good

You can use the password_verify

if (password_verify('12345', 'sajEeYaHYyeSU')) {
    echo 'Senha válida';
} else {
    echo 'Senha errada';
}

Then, you can select in the database, redeem the password in hash and check by php the combinations without encrypting password by password. I believe it is better. You would need to do tests.

  • 1

    Take care of Sqlinjection, all this work for someone to go there and erase the database

  • @Guilhermecostamilam yes, I just showed an example of using SQL. Nor did I use PDO or mysqli. But your remark is valid.

  • Yes, Andrei Coelho, so the verification will have to be with password_verify() for sure. But I’m stuck how to make this combination of passwords, being that comes the array with the combinations and the value that was clicked

  • @Joséarijunior You need to use javascript. Want an example?

  • Send @Andrei Coelho...

Browser other questions tagged

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