django-otp

So recently, actually not so recently, I started working on my GSOC project to provide Registration with phone numbers on Cadasta Platform. Registration with phone number requires verifying the phone number. Verifying a phone number, is a simple procedure 
1) User enters a phone number to register with.
2) Generate and send a One-Time Password(otp) to the registered phone number.
3) User enters otp.
4) If otp is valid, mark the phone as verified, else throw an error.

One-Time Passwords are, as the name suggests, passwords that can only be used once. If a password has been verified once, it should be marked as expired.

My mentor has given me the liberty to use any tool I like to implement the phone registration feature, and so I decided to use django-otp.

There are many packages out there which can be used to generate otps, one such package that I know about is PyOTP. But the one that I am using currently and which I am going to write about today is django-otp. Although django-otp is used as a third party application in many other django packages, and it has a pretty good documentation, I didn’t find many article on it by people who’ve actually used it. I actually didn’t find any article, so as a part of my GSOC program I decided to write one myself.(If you know of any article as such, do let me know in the comments.)

django-otp provides mainly 2 algorithms with which we can generate an otp. 1) HOTP
2) TOTP

Glossary: prover — is the person who we’re trying to verify, the one who enters the OTP. verifier — is the person who is trying to verify someone, who generates OTP.

HOTP
HOTP is an algorithm that generates a pseudo-random sequence of codes based on an increment counter. Every time a prover generates a new code or a verifier verifies one, they increment their respective counters. This algorithm will fail if the prover generates too many codes without a successful verification.

Here’s a small example of how OTP tokens are generated with HOTP is generated. We have a secret_key which will be used to generate tokens. This key, as the name suggests, will be a secret. hotp is a function which generates token by using HOTP algorithm. counter is the increment counter. We can provide the number of digits in an OTP by passing a value to the parameter digits.

from django_otp.oath import hotp
secret_key = b'1234567890123467890'
for counter in range(5):
print(hotp(key=secret_key,counter=counter,digits=6))
===========================Output===================================
755224
287082
359152
969429
338314

TOTP
TOTP is an algorithm that generates a pseudo-random sequence of codes based on the current time. A typical implementation will change codes every 30 seconds, although this is configurable. This algorithm will fail if the prover and verifier have clocks that drift too far apart.

Here’s a small example of how OTP tokens are generate with TOTP algorithm. TOTP basically uses hotp to generates time-based OTPs, but instead of using simple counter, it uses time as a counter. Here we provide a parameter step which, in a simple language denotes time period for which a token should be considered valid. Here step is 10, so every token will be considered valid for 10 seconds. Default value for a step is 30 seconds, and for digits it is 6.

from django_otp.oath import totp
import time
secret_key = b'12345678901234567890'
now = int(time.time())
for delta in range(10,110,20):
print(totp(key=secret_key, step=10, digits=6, t0=(now-delta)))
==============================Output================================
287082
969429
254676
162583
520489

There is one other way with which we can generate tokens, and that is by creating a TOTP object. But more on that in my next article. There are many things which might sound confusing here, I’ll make sure I clear those confusions in my next article as well.