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
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 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
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 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.