Closed ghost closed 6 years ago
$secret = $request->input('secret');
is an example of how to get the user input. In your code, the equivalent line is $input = $_POST['textfield-verify-code'];
so you would supply $input
to the verifyKey method as the secret.
There is another issue with the code:
$tfa_secretkey = $google2fa->generateSecretKey();
$input = $_POST['textfield-verify-code'];
$valid = $google2fa->verifyKey($tfa_secretkey, $secret, $window);
If you generate a new, random secret key the user input won't verify against it. $tfa_secretkey
needs to have been the one the user previously scanned into their authentication app.
In the documentation it looks like this:
$valid = $google2fa->verifyKey($user->google2fa_secret, $secret);
$user->google2fa_secret
is referring to the user's existing secret key.
Thank you, but I keep getting the same error message. Have I missed something?
use PragmaRX\Google2FA\Google2FA;
$google2fa = new Google2FA();
$tfa_secretkey = $google2fa->generateSecretKey();
$input = $_POST['textfield-verify-code']; # This is the input that the user enters theirs TOTP
$secret = $request->input('secret');
# $window = 8;
$valid = $google2fa->verifyKey($user->google2fa_secret, $secret);
echo $valid;
UPDATE 1
I got now a new error message from the code below: Uncaught PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException: Secret key is too short. Must be at least 16 base32 characters in
use PragmaRX\Google2FA\Google2FA;
$google2fa = new Google2FA();
$tfa_secretkey = $google2fa->generateSecretKey(16);
$input = $_POST['textfield-verify-code']; # This is the input that the user enters theirs TOTP
# $secret = $request->input('secret');
# $window = 8;
$valid = $google2fa->verifyKey($user->google2fa_secret, $input);
echo $valid;
UPDATE 2 I have read your answer once more and changed a lot in my code. Still, I'm getting the same error message as in update 1.
site-settings.php
require_once $url_homebase.'vendor/autoload.php';
# USE
use Swap\Builder;
use DeviceDetector\DeviceDetector;
use DeviceDetector\Parser\Device\DeviceParserAbstract;
use Hackzilla\PasswordGenerator\Generator\ComputerPasswordGenerator;
use PragmaRX\Google2FA\Google2FA;
# VARIABLES
$google2fa = new Google2FA();
$secretKey = $google2fa->generateSecretKey(64);
$generator = new ComputerPasswordGenerator();
$generator->setUppercase()->setLowercase(false)->setNumbers()->setSymbols(false)->setLength(18);
$generate_password = $generator->generatePasswords(1);
$builder = new Builder();
$swap = $builder->add('fixer')->build();
# $rate = $swap->historical('SEK/'.$currency_to, (new \DateTime())->modify('-1 day'));
?>
site-settings-twfa.php
<?php
# REQUIRE
# require_once '../../configs/site-settings.php';
require_once '../../configs/site-connection.php';
require_once '../../configs/site-functions.php';
require_once '../../configs/site-database.php';
require_once '../../vendor/autoload.php';
use PragmaRX\Google2FA\Google2FA;
$google2fa = new Google2FA();
# VARIABLES
$secret = $_POST['textfield-verify-code'];
$valid = $google2fa->verifyKey($user['data_tfa_secret'], $secret, 4);
echo $valid;
?>
If I change $secretKey = $google2fa->generateSecretKey(64);
to the following:
$prefix = str_pad($user['id_user'], 10, 'X');
$secretKey = $google2fa->generateSecretKey(32, $prefix);
I'll get the following error message:
Fatal error: Uncaught PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException: This secret key is not compatible with Google Authenticator. in H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Support\Base32.php:118 Stack trace: #0 H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Support\Base32.php(105): PragmaRX\Google2FA\Google2FA->checkGoogleAuthenticatorCompatibility('GFMFQWCYLBMFQWC...') #1 H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Support\Base32.php(29): PragmaRX\Google2FA\Google2FA->validateSecret('GFMFQWCYLBMFQWC...') #2 H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Google2FA.php(70): PragmaRX\Google2FA\Google2FA->generateBase32RandomKey(32, '1XXXXXXXXX') #3 H:\www\min-ekonomi\configs\site-settings.php(80): PragmaRX\Google2FA\Google2FA->generateSecretKey(32, '1XXXXXXXXX') #4 H:\www\min-ekonomi\index.php(4): require_once('H:\\www\\min-ekon...') #5 {main} thrown in H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Support\Base32.php on line 118
I think the first code block looked good apart from the $secret = $request->input('secret');
Update 1: the user input will not be able to validate against a secret key that has been just created. If $user->google2fa_secret
is not defined that would explain the error.
Update 2: The first two code blocks have issues but this should work, check that everything is defined:
$secret = $_POST['textfield-verify-code'];
$valid = $google2fa->verifyKey($user['data_tfa_secret'], $secret, 4);
The last error is caused by the code not producing a GA-compatible secret key. Applying the solution provided in the docs:
$prefix = str_pad($user['id_user'], 10, 'X');
$prefix = str_pad($prefix, pow(2,ceil(log(strlen($prefix),2))), 'X');
$secretKey = $google2fa->generateSecretKey(32, $prefix);
My suggestion would be to keep things as simple as possible to start with in order to get it working properly. Just do the bare minimum with defaults and go from there.
Thank you for your answer. Unfortunately I'll get the same error message when I tested your code. Everything is defined, as you can see in UPDATE 1
.
I tested to add $google2fa->setEnforceGoogleAuthenticatorCompatibility(false);
which removed the error message that is mentioned in UPDATE 2
. I scanned the QR-code that had this key: GFMFQWCYLBMFQWCYLBMFQWCYLASYUJG2A5YY5I7XJFWPOL27OAHFQN6DZ7
. After that, I tested to enter the TOTP from the app. Here's the result from the console:
<br />
<b>Notice</b>: Undefined variable: user in <b>H:\www\min-ekonomi\ajax\post\save-settings-twfa.php</b> on line <b>16</b><br />
<br />
<b>Fatal error</b>: Uncaught PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException: Secret key is too short. Must be at least 16 base32 characters in H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Google2FA.php:194
Stack trace:
#0 H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Google2FA.php(49): PragmaRX\Google2FA\Google2FA->oathHotp('', 50777019)
#1 H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Google2FA.php(332): PragmaRX\Google2FA\Google2FA->findValidOTP(NULL, '273234', 4, 50777019, 50777023, '__not_set__')
#2 H:\www\min-ekonomi\ajax\post\save-settings-twfa.php(16): PragmaRX\Google2FA\Google2FA->verifyKey(NULL, '273234', 4)
#3 {main}
thrown in <b>H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Google2FA.php</b> on line <b>194</b><br />
site-settings.php
require_once $url_homebase.'vendor/autoload.php';
# USE
use Swap\Builder;
use DeviceDetector\DeviceDetector;
use DeviceDetector\Parser\Device\DeviceParserAbstract;
use Hackzilla\PasswordGenerator\Generator\ComputerPasswordGenerator;
use PragmaRX\Google2FA\Google2FA;
# VARIABLES
$google2fa = new Google2FA();
$google2fa->setEnforceGoogleAuthenticatorCompatibility(false);
$prefix = str_pad($user['id_user'], 10, 'X');
$prefix = str_pad($prefix, pow(2, ceil(log(strlen($prefix), 2))), 'X');
$secretKey = $google2fa->generateSecretKey(32, $prefix);
$generator = new ComputerPasswordGenerator();
$generator->setUppercase()->setLowercase(false)->setNumbers()->setSymbols(false)->setLength(18);
$generate_password = $generator->generatePasswords(1);
$builder = new Builder();
$swap = $builder->add('fixer')->build();
# $rate = $swap->historical('SEK/'.$currency_to, (new \DateTime())->modify('-1 day'));
?>
I am sorry, but I am totally new to this kind of security method.
H:\www\min-ekonomi\ajax\post\save-settings-twfa.php(16): PragmaRX\Google2FA\Google2FA->verifyKey(NULL, '273234', 4)
That looks to me like you called verifyKey()
with NULL as the secret key. Check the value of the secret key before this is called.
Aha! The file couldn't fetch user's information. That is now fixed, but it still give me an error message.
<b>Fatal error</b>: Uncaught PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException: This secret key is not compatible with Google Authenticator. in H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Support\Base32.php:118
Stack trace:
#0 H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Support\Base32.php(105): PragmaRX\Google2FA\Google2FA->checkGoogleAuthenticatorCompatibility('GFMFQWCYLBMFQWC...')
#1 H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Support\Base32.php(47): PragmaRX\Google2FA\Google2FA->validateSecret('GFMFQWCYLBMFQWC...')
#2 H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Google2FA.php(191): PragmaRX\Google2FA\Google2FA->base32Decode('GFMFQWCYLBMFQWC...')
#3 H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Google2FA.php(49): PragmaRX\Google2FA\Google2FA->oathHotp('GFMFQWCYLBMFQWC...', 50777087)
#4 H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Google2FA.php(332): PragmaRX\Google2FA\Google2FA->findValidOTP('GFMFQWCYLBMFQWC...', '726255', 4, 50777087, 50777091, '__not_set__')
#5 H:\www\min-ek in <b>H:\www\min-ekonomi\vendor\pragmarx\google2fa\src\Support\Base32.php</b> on line <b>118</b><br />```
Can you just use $secretKey = $google2fa->generateSecretKey();
to get things working?
Oh my! Now it's finally working! Many thanks for your help!
it is not Secret key is too short. Must be at least 16 base32 characters
I have sort of the same problem as what JordyKroeze had. Even if I have entered the TOTP from Authenticator Plus after I scanned the QR code, it only generate
Uncaught Error: Call to a member function input() on null in ...
. Why?Here's is my current code: