Open In App

One Time Password (OTP) algorithm in Cryptography

Last Updated : 06 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Authentication, the process of identifying and validating an individual is the rudimentary step before granting access to any protected service (such as a personal account). Authentication has been built into the cyber security standards and offers to prevent unauthorized access to safeguarded resources. Authentication mechanisms today create a double layer gateway prior to unlocking any protected information. This double layer of security, termed as two factor authentication, creates a pathway that requires validation of credentials (username/email and password) followed by creation and validation of the One Time Password (OTP). The OTP is a numeric code that is randomly and uniquely generated during each authentication event. This adds an additional layer of security, as the password generated is fresh set of digits each time an authentication is attempted and it offers the quality of being unpredictable for the next created session. The two main methods for delivery of the OTP is:

  1. SMS Based: This is quite straightforward. It is the standard procedure for delivering the OTP via a text message after regular authentication is successful. Here, the OTP is generated on the server side and delivered to the authenticator via text message. It is the most common method of OTP delivery that is encountered across services.
  2. Application Based: This method of OTP generation is done on the user side using a specific smartphone application that scans a QR code on the screen. The application is responsible for the unique OTP digits. This reduces wait time for the OTP as well as reduces security risk as compared to the SMS based delivery.

The most common way for the generation of OTP defined by The Initiative For Open Authentication (OATH) is the Time Based One Time Passwords (TOTP), which is a Time Synchronized OTP. In these OTP systems, time is the cardinal factor to generate the unique password. The password generated is created using the current time and it also factors in a secret key. An example of this OTP generation is the Time Based OTP Algorithm (TOTP) described as follows:

  1. Backend server generates the secret key
  2. The server shares secret key with the service generating the OTP
  3. A hash based message authentication code (HMAC) is generated using the obtained secret key and time. This is done using the cryptographic SHA-1 algorithm. Since both the server and the device requesting the OTP, have access to time, which is obviously dynamic, it is taken as a parameter in the algorithm. Here, the Unix timestamp is considered which is independent of time zone i.e. time is calculated in seconds starting from January First 1970. Let us consider “0215a7d8c15b492e21116482b6d34fc4e1a9f6ba” as the generated string from the HMAC-SHA1 algorithm.
  4. The code generated is 20 bytes long and is thus truncated to the desired length suitable for the user to enter. Here dynamic truncation is used. For the 20-byte code “0215a7d8c15b492e21116482b6d34fc4e1a9f6ba”, each character occupies 4 bits. The entire string is taken as 20 individual one byte string. We look at the last character, here a. The decimal value of which is taken to determine the offset from which to begin truncation. Starting from the offset value, 10 the next 31 bits are read to obtain the string “6482b6d3″. The last thing left to do, is to take our hexadecimal numerical value, and convert it to decimal, which gives 1686288083. All we need now are the last desired length of OTP digits of the obtained decimal string, zero-padded if necessary. This is easily accomplished by taking the decimal string, modulo 10 ^ number of digits required in OTP. We end up with “288083” as our TOTP code.
  5. A counter is used to keep track of the time elapsed and generate a new code after a set interval of time
  6. OTP generated is delivered to user by the methods described above.

Apart from the time-based method described above, there also exist certain mathematical algorithms for OTP generation for example a one-way function that creates a subsequent OTP from the previously created OTP. The two factor authentication system is an effective strategy that exploits the authentication principles of “something that you know” and “something that you have”.The dynamic nature of the latter principle implemented by the One Time Password Algorithm is crucial to security and offers an effective layer of protection against malicious attackers. The unpredictability of the OTP presents a hindrance in peeling off the layers that this method of cryptography has to offer.

Example :

we’ll create a simple One Time Password (OTP) algorithm using Python’s built-in ‘secrets' module. The OTP algorithm will generate a random one-time password, which will be used as a secure authentication token for a user.

Explanation: The OTP algorithm will use a secret key (a random string) to generate the one-time password. The ‘secret’ key should be kept secure and not shared with others. The secrets module provides a strong source of randomness to generate the key securely.

We’ll use the ‘secrets.token_hex()' function to generate a random secret key and the ‘secrets.choice()' function to create a random OTP by choosing characters randomly from a predefined set.

Let’s see the code and the output:

Java




// Java program to illustrate OTP algorithm
import java.security.SecureRandom;
 
// Driver Class
class GFG {
    // Function to generate a random secret key
    public static String generateSecretKey()
    {
        SecureRandom secureRandom = new SecureRandom();
        byte[] bytes = new byte[16];
         
          secureRandom.nextBytes(bytes);
        StringBuilder secretKey = new StringBuilder();
       
        for (byte b : bytes) {
            secretKey.append(String.format("%02x", b));
        }
       
        return secretKey.toString();
    }
 
    // Function to generate a One Time Password (OTP) using
    // the secret key
    public static String generateOTP(String secretKey,int length)
    {
        String allowedCharacters = "0123456789";
        StringBuilder otp = new StringBuilder();
        SecureRandom secureRandom = new SecureRandom();
       
        for (int i = 0; i < length; i++) {
            int randomIndex = secureRandom.nextInt(allowedCharacters.length());
            otp.append(allowedCharacters.charAt(randomIndex));
        }
       
        return otp.toString();
    }
 
    public static void main(String[] args)
    {
        // Generate a random secret key
          // (this should be kept secure)
        String secretKey = generateSecretKey();
 
        // Simulate sending the OTP to the user
        int otpLength = 6;
        String otp = generateOTP(secretKey, otpLength);
 
        // Simulating user input for OTP verification
        java.util.Scanner scanner = new java.util.Scanner(System.in);
        System.out.print("Please enter the received OTP: ");
        String userInput = scanner.next();
 
        // Verify the OTP entered by the user
        if (userInput.equals(otp)) {
            System.out.println("OTP verification successful. Access granted!");
        }
        else {
            System.out.println("OTP verification failed. Access denied!");
        }
    }
}


Python




import secrets
 
# Function to generate a random secret key
def generate_secret_key():
    return secrets.token_hex(16# 16 bytes (32 hex characters)
 
# Function to generate a One Time Password (OTP) using the secret key
def generate_otp(secret_key, length=6):
    # Defining the characters allowed in the OTP
    allowed_characters = "0123456789"
 
    # Generating a random OTP using the secret key and allowed characters
    otp = ''.join(secrets.choice(allowed_characters) for _ in range(length))
     
    return otp
 
# Example usage
if __name__ == "__main__":
    # Generate a random secret key (this should be kept secure)
    secret_key = generate_secret_key()
 
    # Simulate sending the OTP to the user
    otp = generate_otp(secret_key)
 
    # Simulating user input for OTP verification
    user_input = input("Please enter the received OTP: ")
 
    # Verify the OTP entered by the user
    if user_input == otp:
        print("OTP verification successful. Access granted!")
    else:
        print("OTP verification failed. Access denied!")


Output:

Please enter the received OTP: 123456
OTP verification successful. Access granted!

Explanation of the above code

  1. The ‘generate_secret_key()' function generates a 16-byte (32 hexadecimal characters) random secret key using ‘secrets.token_hex()'. You can adjust the length if needed, but 16 bytes is considered secure.
  2. The ‘generate_otp()' function takes the secret key and an optional length argument (default is 6) to specify the length of the OTP. It creates an OTP by randomly choosing characters from the string “0123456789” (numbers only) and returns the OTP.
  3. In the example usage, we generate a random secret key using ‘generate_secret_key()'. This key should be kept secure and not shared.
  4. We simulate sending the OTP to the user by calling ‘generate_otp(secret_key)' and storing the OTP in the variable ‘otp'.
  5. We ask the user to input the received OTP and store it in the variable ‘user_input'.
  6. Finally, we compare the user-inputted OTP with the generated OTP. If they match, the user is granted access, otherwise, access is denied.


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads