Time-based One-time Password (TOTP)?, How to use it in Ruby On Rails API?
Intro
Security is paramount in today's digital world. Two-factor authentication (2FA) adds an extra layer of protection beyond just usernames and passwords. While SMS OTP is a common 2FA method, it can be costly, but TOTP (Time-Based One-Time Password), is a free and secure alternative using authenticator apps like Google Authenticator. This subject dives into the world of TOTP 2FA, exploring its functionalities and implementation within Ruby on Rails applications.
Authentication
The Essence of Authentication(Who Are You?):
Authentication revolves around establishing a user's legitimacy. When you attempt to access a system, it needs to confirm that you are indeed the authorized user you claim to be. This verification process ensures that only rightful individuals access sensitive information or functionalities.
Methods of Authentication(Proving Your Identity):
There are various ways to authenticate users. Here's a closer look at some common methods:
Knowledge-based: This involves providing a secret piece of information known only to the user and the system, such as a username and password combination.
Token-based: These methods involve a unique token, like a physical security key or a code generated by an authentication app, that verifies your identity.
Biometric: These methods rely on unique physical or physiological characteristics, such as fingerprints, facial recognition, or voice patterns, for user verification.
How Authentication Works(Behind the Scenes):
Mechanics of authentication using the common username and password method:
Account Creation: You create a unique username and password to establish your identity within the system. These credentials are securely stored on the server.
Verification at Login: When you attempt to log in, you enter your username and password. The system retrieves the stored credentials associated with your username and compares them to the ones you entered.
Granting Access: If the provided credentials match the stored information, the system authenticates the user and grants access.
Authentication vs. Authorization(Understanding the Difference):
- While authentication verifies who you are, authorization determines what you can do within a system. Authentication ensures you are a legitimate user, while authorization dictates the specific actions or resources you are allowed to access based on your assigned permissions.
Authentication Methods
Authentication comes in various forms, each offering different levels of security. Let's explore the common ones:
Single-Factor Authentication (SFA): This is the simplest method, relying on a single credential like a username and password. While convenient, it's considered weak as compromising one-factor grants access.
Multi-Factor Authentication (MFA) strengthens online account security by requiring multiple verification methods for login, think of it like adding extra locks to your door.
Two-Factor Authentication (2FA) uses two factors:
Something you know (password or PIN).
Something you have (security token, smartphone app code, SMS/email code).
Example: Entering your bank password (something you know) and then a code from your banking app (something you have).
Example: SMS, TOTP, Pre-generated Code, push, and U2F security keys.
Three-Factor Authentication (3FA) adds another layer on top of 2FA:
Something you are (fingerprint, face recognition, iris scan).
Example: Using 2FA with fingerprint recognition for high-security applications.
Single Sign-On (SSO): This allows users to access multiple applications with one set of credentials (e.g., logging into other apps using Google or Facebook). While convenient, it relies on a trusted third party for authentication.
TOTP
What is TOTP?
TOTP, standing for Time-based One-Time Password, is a powerful and widely used method for two-factor authentication (2FA). It significantly enhances account security by requiring a unique, temporary code alongside your traditional username and password, the time-based passwords are available offline without connection to internet or have signal in mobile.
How Does TOTP Work?
The magic of TOTP lies in its reliance on the current time and a shared secret between your device and the application you're trying to access. Here's a breakdown of the process:
Secret Sharing: During initial setup, the application generates a secret key. This key can be displayed as a QR code or a string of characters.
Authenticator App Integration: You scan the QR code or enter the secret key into a TOTP-compatible authenticator app on your smartphone (e.g., Google Authenticator, Microsoft Authenticator), also you can use your pc.
Code Generation: The authenticator app uses the secret key, along with the current time synchronized with internet servers (for initial setup), to generate a unique, time-sensitive code.
Verification: When logging in to the application, you enter your username, password, and the current code displayed by the authenticator app. The application verifies the code based on the shared secret and the current time, granting access only if it matches.
Benefits of TOTP:
Enhanced Security: By adding a layer of time-based verification, TOTP significantly reduces the risk of unauthorized access. Even if your password is compromised, attackers wouldn't have the valid code needed to log in.
Offline Functionality: Unlike SMS-based 2FA, TOTP codes are generated on your device, making them usable even without a cellular connection.
User-Friendly: TOTP is convenient for users. Once set up, the authenticator app readily displays the required code, streamlining the login process.
Cost-Effective: Unlike methods relying on SMS messages, TOTP doesn't incur additional communication charges.
TOTP vs. Other 2FA Methods:
SMS-based 2FA: While convenient, SMS-based 2FA is less secure as attackers can potentially intercept SMS messages through SIM-swapping techniques.
Hardware Tokens: Hardware tokens, like security keys, offer strong security but can be inconvenient to carry around.
HOTP vs. TOTP:
HOTP: The “H” in HOTP stands for Hash-based Message Authentication Code (HMAC), let's explain more:
HMAC: This refers to a specific way of creating a cryptographic hash (a unique string of characters) based on a secret key and some data.
One-Time Password (OTP): This is a unique code that's only valid for a single login attempt.
For more details.
TOTP is a robust and user-friendly 2FA solution that significantly enhances account security without significant drawbacks. By leveraging the shared secret and the current time, TOTP generates unique codes that make unauthorized access incredibly difficult. Integrating TOTP into your application can significantly strengthen your user authentication system.
Implementing TOTP 2FA in Ruby on Rails:
I am using:
Ruby version 3.2.2.
Ruby on Rails version 7.1.3.4
Users Table for process TOTP.
Step 1
gem 'rotp' # 6.3.0 gem 'rqrcode' # 2.2.0
Run
bundle install
to install the gems.rotp
: This gem offers functionalities for working with TOTP algorithms in Ruby. It provides classes and methods to generate and verify one-time codes.rqrcode
: This gem to generate QR codes. Users can scan these codes with their authenticator apps to link them to their accounts for 2FA.Step 2
Add a New Column for OTP Secret: You need to store a secret key for each user, which will be used to generate and verify TOTP codes. Add a new column, let's name it
otp_secret
to theusers
table,otp_secret
acts as a secret handshake between the user and your application. It's a critical piece of information used to generate unique one-time codes specific to each user.class AddOtpSecretColumnToUsers < ActiveRecord::Migration[7.1] def change add_column :users, :otp_secret, :string end end
Step 3
Implement a setup method to set up TOTP for a user. This involves generating a secret key, creating a TOTP object, and generating a QR code for the user to scan with their TOTP app.
def setup otp_secret = ROTP::Base32.random totp = ROTP::TOTP.new(otp_secret, issuer: 'TrainingApp') if current_user.update!(otp_secret: otp_secret) qr_code = RQRCode::QRCode.new(totp.provisioning_uri(current_user.email)).as_png(resize_exactly_to: 200) render json: { qr_code: Base64.encode64(qr_code.to_s) } else render json: { error: current_user.errors.full_messages }, status: :unprocessable_entity end end
ROTP::Base32.random
A secure random number generator produces random bytes, which encoded into a Base32 string, Base32 encoding converts binary data into a human-readable format using 32 ASCII characters, resulting Base32 string can be used as a secret key.ROTP::
TOTP.new
(otp_secret, issuer: 'TrainingApp')
code initializes a new instance and receiveotp_secret
Base32 encoded secret key for generating the OTP,issuer
key an optional parameter that specifies the issuer of the OTP, which is displayed in the user’s authenticator app when they scan the QR code.Update User:
current_user.update!(otp_secret: otp_secret)
saves the secret key to the user’s record, to be use it when verify the OTP in verify action.RQRCode::QRCode.new(totp.provisioning_uri(current_user.email)).as_png(resize_exactly_to: 200)
:RQRCode::QRCode
creates a QR code that the user can scan to set up TOTP in their app.totp.provisioning_uri(current_user.email)
generates a provisioning URI for the TOTP instance,as_png(resize_exactly_to: 200)
converts the provisioning URI into a PNG image of a QR code, with resizes the image to 200x200 pixels.Base64.encode64(qr_code.to_s)
converted to a Base64 string and returned in the JSON response.Using script in the Postman App to convert the Base64 QR code string in response into QR code Image:
var template = ` <img src="data:image/png;base64,{{response.qr_code}}" /> `; function constructVisualizerPayload() { var res = pm.response.json(); return {response: res}; } pm.visualizer.set(template, constructVisualizerPayload());
Try to Scan the QR code using QR code app not using authenticator app, you will see same like this:
otpauth://totp/TrainingApp:user1%40example.com?secret=LXIL7KO3X2HQAS6RGYW3EKWJVRWMDFO2&issuer=TrainingApp
Step 4
Verifying TOTP action: Implement a method to verify the TOTP code entered by the user
def verify totp = ROTP::TOTP.new(current_user.otp_secret, issuer: 'TrainingApp') consumed_timestep = totp.verify(params[:otp_attempt].to_s, drift_behind: 15) if consumed_timestep current_user.update!(consumed_timestep: consumed_timestep) render json: { message: 'Successfully configured OTP protection for your account' }, status: :ok else render json: { error: 'The code you provided was invalid!' }, status: :unprocessable_entity end end
ROTP::
TOTP.new
(current_user.otp_secret, issuer: 'TrainingApp')
initializes a new instance with passotp_secret
that created in the setup action and saved in the user table,issuer
key an optional parameter that specifies the issuer of the OTP.The
totp.verify
method checks the provided OTP against the current OTP generated by the TOTP instance. It compares the user's OTP attempt with the one generated from the secret key and current time. Thedrift_behind
parameter allows the method to accept OTPs from up to 15 second previous time (usually 30 seconds), accommodating slight time differences between the server and the user's device. If the OTP is correct, it returns a timestamp, if not, it returns nil.Update User: If the TOTP code is valid, the user’s record is updated (you might use this to store the last valid
timestep
or other relevant information).Render Response: Depending on the verification result, an appropriate JSON response is rendered. For more information browser the Rotp Gem.
The implementation of TOTP 2FA in application depends heavily on specific requirements and security considerations, factors influencing the implementation include:
Authentication Strategy: The existing authentication system will dictate how TOTP integration fits in.
User Experience: Balancing security with user convenience is essential. Consider the user flow for enabling, disabling, and using 2FA.
Security Best Practices: Proper storage of the OTP secret, handling potential security risks, and adhering to industry standards are crucial.
Summary
TOTP uses a shared secret key and synchronized clocks on both the user's device and the server to generate unique, time-limited codes. Users typically set this up by scanning a QR code into an authenticator app. While offering enhanced security over SMS-based 2FA by eliminating reliance on cellular networks, TOTP still requires manual code input and is less universally accessible due to smartphone ownership. Secure storage of the shared secret is crucial, as its compromise could lead to account takeover.
References
My articles
Subscribe to my newsletter
Read articles from Saleh Alhaddad directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Saleh Alhaddad
Saleh Alhaddad
Seasoned Ruby on Rails Backend Developer with 6 years of experience building scalable web applications. Proficient in crafting robust RESTful APIs, optimizing database performance, and leveraging cloud technologies (AWS, Docker, Kubernetes) to deliver exceptional user experiences. Passionate about Agile development, CI/CD pipelines, and contributing to open-source communities. Let's build amazing software together!