[GH-ISSUE #57] Adding any prefix generates an unusable secret #495

Closed
opened 2026-03-14 11:57:49 +03:00 by kerem · 5 comments
Owner

Originally created by @melvinchia on GitHub (Mar 7, 2017).
Original GitHub issue: https://github.com/antonioribeiro/google2fa/issues/57

When I tried using no prefix:
$otp_secret = $google2fa->generateSecretKey(16);
It generates a usable secret, tested by Authy on iOS (manually key in the secret, or QR code scan)

When I tried using a blank prefix:
$otp_secret = $google2fa->generateSecretKey(16, '');
It generates a usable secret, tested by Authy on iOS (manually key in the secret, or QR code scan)

When I add a prefix prefix:
$otp_secret = $google2fa->generateSecretKey(16, 'm');
$otp_secret = $google2fa->generateSecretKey(16, 'mel');
$otp_secret = $google2fa->generateSecretKey(16, 'melvin');
All 3 lines yield an error, whether manually keying in the secret, or QR code scan.

Anybody else encounter this problem?

Originally created by @melvinchia on GitHub (Mar 7, 2017). Original GitHub issue: https://github.com/antonioribeiro/google2fa/issues/57 When I tried using no prefix: `$otp_secret = $google2fa->generateSecretKey(16);` It generates a usable secret, tested by Authy on iOS (manually key in the secret, or QR code scan) When I tried using a blank prefix: `$otp_secret = $google2fa->generateSecretKey(16, '');` It generates a usable secret, tested by Authy on iOS (manually key in the secret, or QR code scan) When I add a prefix prefix: `$otp_secret = $google2fa->generateSecretKey(16, 'm');` `$otp_secret = $google2fa->generateSecretKey(16, 'mel');` `$otp_secret = $google2fa->generateSecretKey(16, 'melvin');` All 3 lines yield an error, whether manually keying in the secret, or QR code scan. Anybody else encounter this problem?
kerem closed this issue 2026-03-14 11:57:54 +03:00
Author
Owner

@JC5 commented on GitHub (Apr 2, 2017):

Yes, but this is a problem I only encounter on iOS.

https://github.com/firefly-iii/firefly-iii/issues/624

<!-- gh-comment-id:290967332 --> @JC5 commented on GitHub (Apr 2, 2017): Yes, but this is a problem I only encounter on iOS. https://github.com/firefly-iii/firefly-iii/issues/624
Author
Owner

@melvinchia commented on GitHub (Apr 3, 2017):

Strange, I received a suggestion thru email, but I don't see it on Github.
Is there a reason why it didn't appear?

On Mon, Mar 20, 2017 at 7:34 AM, Milan notifications@github.com wrote:

I believe if we subtract the length of the prefix here it may fix the
issue... haven't tested it myself yet:
public function generateSecretKey($length = 16, $prefix = '') { $b32 = '
234567QWERTYUIOPASDFGHJKLZXCVBNM'; $secret = $prefix ?
$this->toBase32($prefix) : ''; $length = $prefix? ($length -
count($prefix)):$length; for ($i = 0; $i < $length; $i++) { $secret .=
$b32[$this->getRandomNumber()]; } $this->validateSecret($secret); return
$secret; }


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/antonioribeiro/google2fa/issues/57#issuecomment-287657399,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ACS_RU-zAey0sqa5hHvPNtAHAEKng694ks5rnbt5gaJpZM4MVJY8
.

<!-- gh-comment-id:291052070 --> @melvinchia commented on GitHub (Apr 3, 2017): Strange, I received a suggestion thru email, but I don't see it on Github. Is there a reason why it didn't appear? On Mon, Mar 20, 2017 at 7:34 AM, Milan <notifications@github.com> wrote: > I believe if we subtract the length of the prefix here it may fix the > issue... haven't tested it myself yet: > public function generateSecretKey($length = 16, $prefix = '') { $b32 = ' > 234567QWERTYUIOPASDFGHJKLZXCVBNM'; $secret = $prefix ? > $this->toBase32($prefix) : ''; $length = $prefix? ($length - > count($prefix)):$length; for ($i = 0; $i < $length; $i++) { $secret .= > $b32[$this->getRandomNumber()]; } $this->validateSecret($secret); return > $secret; } > > — > You are receiving this because you authored the thread. > Reply to this email directly, view it on GitHub > <https://github.com/antonioribeiro/google2fa/issues/57#issuecomment-287657399>, > or mute the thread > <https://github.com/notifications/unsubscribe-auth/ACS_RU-zAey0sqa5hHvPNtAHAEKng694ks5rnbt5gaJpZM4MVJY8> > . >
Author
Owner

@melvinchia commented on GitHub (Apr 3, 2017):

What puzzles me is, there's also a way to generate a "more secure" secret key using:
$otp_secret = $google2fa->generateSecretKey(32);

So is it that what is passed in "must add up to 16 or 32 characters", or does subtracting number of letters in the prefix from the number passed to the generateSecretKey function matter in this case?

<!-- gh-comment-id:291052321 --> @melvinchia commented on GitHub (Apr 3, 2017): What puzzles me is, there's also a way to generate a "more secure" secret key using: $otp_secret = $google2fa->generateSecretKey(32); So is it that what is passed in "must add up to 16 or 32 characters", or does subtracting number of letters in the prefix from the number passed to the generateSecretKey function matter in this case?
Author
Owner

@melvinchia commented on GitHub (Apr 10, 2017):

@antonioribeiro , just to clarify, the purpose of the following (sub)function:

$secretKey = $google2fa->generateSecretKey(16, $userId);

Was documented as "prefixing the secret key", whereby a $userId is provided to the function, which would use the $userId to prefix the salt to generate a 16-bit key. Similarly if 32 is used, the purpose of the $userId is to prefix the salt to generate the key.

Now the explanation seems to be that I have to provide a 16/32-character (padded or full length) $userId which becomes the salt, instead of merely being just a prefix (original intention to increase security)? Am I understanding the explanation wrong here?

<!-- gh-comment-id:292853230 --> @melvinchia commented on GitHub (Apr 10, 2017): @antonioribeiro , just to clarify, the purpose of the following (sub)function: $secretKey = $google2fa->generateSecretKey(16, $userId); Was documented as "prefixing the secret key", whereby a $userId is provided to the function, which would use the $userId to prefix the salt to generate a 16-bit key. Similarly if 32 is used, the purpose of the $userId is to prefix the salt to generate the key. Now the explanation seems to be that I have to provide a 16/32-character (padded or full length) $userId which becomes the salt, instead of merely being just a prefix (original intention to increase security)? Am I understanding the explanation wrong here?
Author
Owner

@antonioribeiro commented on GitHub (Jun 17, 2017):

@melvinchia, I just rewrote that part, trying to make it more clear:

You may prefix your secret keys, but you have to understand that, as your secret key must have length in power of 2, your prefix will have to have a complementary size. So if your key is 16 bytes long, if you add a prefix it must be also 16 bytes long, but as your prefixes will be converted to base 32, the max length of your prefix is 10 bytes. So, those are the sizes you can use in your prefixes:

1, 2, 5, 10, 20, 40, 80...

And it can be used like so:

$prefix = strpad($userId, 10, 'X');

$secretKey = $google2fa->generateSecretKey(16, $prefix);

I've also made a demo site for it: https://pragmarx.com/google2fa.

<!-- gh-comment-id:309192428 --> @antonioribeiro commented on GitHub (Jun 17, 2017): @melvinchia, I just rewrote that part, trying to make it more clear: _You may prefix your secret keys, but you have to understand that, as your secret key must have length in power of 2, your prefix will have to have a complementary size. So if your key is 16 bytes long, if you add a prefix it must be also 16 bytes long, but as your prefixes will be converted to base 32, the max length of your prefix is 10 bytes. So, those are the sizes you can use in your prefixes:_ ``` 1, 2, 5, 10, 20, 40, 80... ``` _And it can be used like so:_ ```php $prefix = strpad($userId, 10, 'X'); $secretKey = $google2fa->generateSecretKey(16, $prefix); ``` I've also made a demo site for it: https://pragmarx.com/google2fa.
Sign in to join this conversation.
No labels
bug
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/google2fa#495
No description provided.