PHPGangsta / GoogleAuthenticator

PHP class to generate and verify Google Authenticator 2-factor authentication
http://phpgangsta.de/4376
BSD 2-Clause "Simplified" License
2.26k stars 699 forks source link

Sync with GA app at the mobile timing and script #44

Closed tcolonel closed 7 years ago

tcolonel commented 7 years ago

Hello.

How I can sync GA app timing at the mobile with PHP script?

In the example I see:

$checkResult = $ga->verifyCode($secret, $oneCode, 2);    // 2 = 2*30sec clock tolerance
if ($checkResult) {
    echo 'OK';
} else {
    echo 'FAILED';
}

But in the GA app another timing ... And when I put code from GA app its valid. But when time is over in the GA app code still valid.

Thanks.

PHPGangsta commented 7 years ago

Can you please be more precise?

The "clock tolerance is +- in both directions. So a tolerance of 2 (which is 2*30seconds => 60 seconds) means:

Because you have no control to sync both clocks (mobile phone + server) exactly, there is a tolerance in both directions. If you want to be more strict, you can set the tolerance to 1 instead of 2, then it's only 30 seconds in both directions. But then you might get more user complains, when the clock of the mobile phone of the users is >=31 seconds wrong :)

tcolonel commented 7 years ago

And what about if clock on the mobile and on the server diff about 3-5 sec. (just checked)?

You can check it at generate code and then check code from mobile by passing GET-params: "secretCode" and "checkCode" - https://tc-development.ru/google/ga/?secretCode="Secret"&checkCode="code from mobile". And you will see problem - at the GA app code changed but on the site its still valid ...

And right now to verify code I use 1 for clock tolerance:

$checkResult = $ga->verifyCode($secret, $oneCode);
if ($checkResult) {
    echo 'OK';
} else {
    echo 'FAILED';
}

And full code is:

<?
require_once('GoogleAuthenticator.php');

$secretCode = (isset($_GET['secretCode']) ? $_GET['secretCode'] : '');
$checkCode  = (isset($_GET['checkCode']) ? $_GET['checkCode'] : '');
$ga         = new PHPGangsta_GoogleAuthenticator();

if(!empty($secretCode) && !empty($checkCode))
{
    if($ga->verifyCode($secretCode, $checkCode))
        echo 'Checking Code is valid';
    else
        echo 'Checking Code is failed';
}
else
{
    $secret = $ga->createSecret();
    echo "<p>Secret is: $secret</p>";

    $qrCodeUrl = $ga->getQRCodeGoogleUrl('tc-development.ru', $secret);
    echo "<p>Google Charts URL for the QR-Code: $qrCodeUrl</p>";
    echo "<p><img src='$qrCodeUrl' alt='QR-Code' /></p>";

    $oneCode = $ga->getCode($secret);
    echo "<p>Checking Code '$oneCode' and Secret '$secret':</p>";

    if($ga->verifyCode($secret, $oneCode))
        echo 'Checking Code is valid';
    else
        echo 'Checking Code is failed';
}
?>

Thanks.

PHPGangsta commented 7 years ago

Sorry, you have to be more precise... For me your website is working as expected.

I go to the website https://tc-development.ru/google/ga/

I'm adding the Secret code(QR-Code) to my GA app. I'm then going to https://tc-development.ru/google/ga/?secretCode="Secret"&checkCode="code from mobile" with the correct values for secretCode and checkCode.

It's valid... If I refresh the site a few times (after 30 seconds, after 45 seconds, after 60 seconds...), then it switches from "valid" to "failed". That is the normal behaviour. The code is valid with a +- tolerance interval of X (whatever you set as $discrepancy).

So even if your app on the mobile phone already shows the next code, the last code is still valid for 30 seconds (or 60 seconds, or whatever your $discrepancy is).

tcolonel commented 7 years ago

So even if your app on the mobile phone already shows the next code, the last code is still valid for 30 seconds (or 60 seconds, or whatever your $discrepancy is).

Ouch ... Sorry, sorry I din't know about it. I was thinking that code must invalid after its changed at GA app. So, now I see that is my fault. Sorry again.

Thank you for attention.

PHPGangsta commented 7 years ago

OK, fine, problem solved. I'll close the issue. Happy to see that there is no bug :)