DEV Community

Cover image for ๐Ÿ›ก๏ธ2FA with Python.
Jothin kumar
Jothin kumar

Posted on • Edited on

๐Ÿ›ก๏ธ2FA with Python.

What is 2FA and why 2FA?๐Ÿค”

2FA stands for two factor authentication. It adds an extra layer of security other than password. The user must enter a 2FA code along with password in order to sign in. 2FA codes can be generated in two ways, time based codes and counter based codes.

Advantages of 2FA over E-Mail or SMS verification:

  • No network required: 2FA codes can be generated offline.
  • ๐Ÿ›ก๏ธ Better security.

Time based codes vs counter based code.

Time based codes Counter based codes
Time based codes changes depending on time. ๐Ÿ•– Counter based codes change depending on number of successful sign-in(s). โœ”๏ธ
No need of adding counter every time in client side. After every successful login, counter must be increased by one in server side as well as client side.

2FA flowchart

2FA with Python

Requirements

  • onetimepass python package (Can be installed using the command: pip install onetimepass).
  • Your favourite authenticator app (Example: Google authenticator, Microsoft authenticator).

Let's start!๐Ÿ‘€

For both time based codes and counter based code, a secret string is securely shared with the authenticator app while setting up 2FA. All codes are generated based on this secret string. This string is not case sensitive.

๐Ÿ•–Time based codes

Let us now, write a simple Python script to understand how time based 2FA works!

from onetimepass import valid_totp
from secrets import choice


def generate_secret():  # Function to return a random string with length 16.
    secret = ''
    while len(secret) < 16:
        secret += choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
    return secret


secret = generate_secret()
print('Enter the following secret in your authenticator app: ', secret)
print("""
Instructions for saving this secret it Google Authenticator:
1. Open Google Authenticator.
2. Click plus icon at the right bottom.
3. Click Enter a setup key.
4. Enter an Account name of your choice and enter the secret provided above.
5. Click Add.
""")
while True:
    otp = int(input('Please enter the otp generated by your authenticator app: '))
    authenticated = valid_totp(otp, secret)
    if authenticated:
        print('Correct otp, Authenticated!')
    elif not authenticated:
        print('Wrong otp, please try again.')
Enter fullscreen mode Exit fullscreen mode

โœ”๏ธ Counter based codes

Here is a complete Python script to understand how counter based 2FA works!

from onetimepass import valid_hotp
from secrets import choice


def generate_secret():  # Function to return a random string with length 16.
    secret = ''
    while len(secret) < 16:
        secret += choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
    return secret


secret = generate_secret()
print('Enter the following secret in your authenticator app: ', secret)
print("""
Instructions for saving this secret it Google Authenticator:
1. Open Google Authenticator.
2. Click plus icon at the right bottom.
3. Click Enter a setup key.
4. Enter an Account name of your choice and enter the secret provided above.
5. Click Add.
""")
while True:
    counter = 0
    otp = int(input('Please enter the otp generated by your authenticator app: '))
    authenticated = valid_hotp(otp, secret)
    if authenticated:
        print('Correct otp, Authenticated!')
        counter += 1
    elif not authenticated:
        print('Wrong otp, please try again.')
Enter fullscreen mode Exit fullscreen mode

Thank you! Leave a comment and a like if you find this article useful :-)

About me

Original article: https://blog.jothin.tech/2fa-with-python

Edit: Thanks to @amoir18 for reporting a mistake.

Top comments (5)

Collapse
 
amoir18 profile image
amoir18

choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567')

This will give a base32 digit error because 0 & 1 are not included in the base32 alphabet

it should be:

choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')

otherwise this is great!

Collapse
 
jothinkumar profile image
Jothin kumar • Edited

Thanks for telling, I changed it.

Collapse
 
rouilj profile image
John P. Rouillard • Edited

Thanks for writing your article, it provided the motivation for implementing HOTP 2fa for the Roundup issue tracker. The HOTP implementation is on the Roundup wiki. I hope to extend it to TOTP in the near future.

Collapse
 
jbrandibas profile image
jbrandibas

I can't get this to work. The code runs, but when I get to the point to enter the otp, it keeps saying the code is wrong. I have tried re-running with multiple keys, but it doesn't ever take the code that is being generated by the authenticator.

Collapse
 
turry profile image
Turry

I never expected this to be so easy ๐Ÿ˜†