1

I'm using pyotp https://github.com/pyotp/pyotp to integrate my application with Google Authenticator.

The documentation suggest using qrious https://github.com/neocotic/qrious this is fine and works well. Essentially qrious is able to generate a QR code purely in the browser. In this case, the provisioning URI is passed to the QR code generator and a QR code is made from that.

The thing that puzzles me is that the provisioning URI contains the secret key, and yet we send this URI to the client end to be turned into a QR code by qrious. So the secret key isn't secret because it has been sent to the client.

I would have expected that the secret key must never be sent out of the back end - what am I failing to understand?

# generate a base32 secret key
>>> pyotp.random_base32()
'55OZSEMXLL7VAUZP'
# make a provisioning_URI
>>> provisioning_URI = pyotp.totp.TOTP('55OZSEMXLL7VAUZP').provisioning_uri('someperson@example.org',issuer_name="FooCorporation")
>>> provisioning_URI
'otpauth://totp/FooCorporation:someperson%40example.org?secret=55OZSEMXLL7VAUZP&issuer=FooCorporation'
>>>

The provisioning_URI gets sent to the browser to be turned into a QR code - but it includes the secret key - surely that's not secure?

Steve Vinoski
  • 19,847
  • 3
  • 31
  • 46
Duke Dougal
  • 24,359
  • 31
  • 91
  • 123
  • The secret key in this context is a shared secret between the server and the client. It differs for every client. – Klaus D. Oct 25 '18 at 02:21
  • So the secret is not an application wide secret? Is it something I need to store in a database field for that user, and retrieve for verification when the user submits a Google Authenticator code to the back end? – Duke Dougal Oct 25 '18 at 02:23
  • You are going to need it to verify the code. – Klaus D. Oct 25 '18 at 02:29

1 Answers1

0

Yes, you should keep it secret from others and share the QR code with the intended users only so they will scan it using their phone app. And you are right. Sending it to the client-side is risky but even if you are going to generate the QR code on the server and show it to the user, still chances are that it may get compromised anytime. The user's phone may get stolen too. So there are a lot of risks. But it is the best idea to generate the QR code on the server and present it to the user so they will scan it. Just don't use any remote solution or any browser extension to generate the code to make your life easier.

In short, you should never consider this form of verification alone and this verification should be always implemented only after the user enters and verify their password.

When it comes to storing the secret key on your server, you should always encrypt it using a technique like this one and then decrypt it on the fly when you need the secret for verification. And obviously, the secret should be generated for each user separately, otherwise, this doesn't make sense. If you will use the same secret, then secrets can be generated for any user by just swapping their emails.

I will once again repeat here that 2FA should never be considered as a standalone security measure. It should be implemented always as the second layer of the authentication.

Rehmat
  • 4,681
  • 3
  • 22
  • 38