Top Open-Source mOTP Libraries for .Net Developers

Written by

in

Securing .NET Applications with mOTP (Mobile One-Time Password)

Two-Factor Authentication (2FA) is a mandatory requirement for modern enterprise applications. While Time-Based One-Time Password (TOTP) systems like Google Authenticator dominate the consumer market, the Mobile One-Time Password (mOTP) protocol remains a highly efficient, open-source alternative for custom infrastructure.

Implementing mOTP in the .NET ecosystem provides a lightweight, highly secure mechanism to safeguard user accounts without relying on proprietary third-party libraries or external paid APIs. What is mOTP?

The mOTP protocol is an open standard designed for creating cryptographically secure, time-synchronized one-time passwords on mobile devices. It differs slightly from standard RFC 6238 (TOTP) in its algorithm footprint and formatting. Core Components of mOTP Secret PIN: A numeric code known only to the user.

Secret Seed: A unique 16-character hexadecimal string shared between the server and the client app.

Epoch Time: The current Unix timestamp, rounded down to the nearest 10-second interval. How mOTP Works Under the Hood

The mOTP algorithm combines simplicity with strong cryptographic primitives.

Time Windowing: The current Unix epoch time in seconds is divided by 10. The resulting integer is converted to a string.

String Concatenation: The system concatenates the time string, the secret seed, and the user’s secret PIN.

MD5 Hashing: The concatenated string is hashed using the MD5 algorithm.

Trimming: The system extracts the first 6 characters of the resulting hexadecimal hash to create the final 6-digit OTP. Implementing mOTP in .NET

Implementing mOTP in native .NET requires no external dependencies beyond the standard System.Security.Cryptography namespace. Below is a production-ready implementation written in C#.

using System; using System.Security.Cryptography; using System.Text; public class MOtpAuthenticator { ///

/// Generates an mOTP token based on the seed, PIN, and a specific time. ///

public static string GenerateToken(string seed, string pin, DateTime utcTime) { // 1. Get Unix timestamp and divide by 10 for the 10-second window long unixTime = ((DateTimeOffset)utcTime).ToUnixTimeSeconds(); long timeWindow = unixTime / 10; // 2. Concatenate Time + Seed + PIN string inputString = $“{timeWindow}{seed}{pin}”; // 3. Compute MD5 Hash using (MD5 md5 = MD5.Create()) { byte[] inputBytes = Encoding.UTF8.GetBytes(inputString); byte[] hashBytes = md5.ComputeHash(inputBytes); // Convert hash bytes to a lowercase hex string StringBuilder sb = new StringBuilder(); foreach (byte b in hashBytes) { sb.Append(b.ToString(“x2”)); } // 4. Return the first 6 characters as the token return sb.ToString().Substring(0, 6); } } ///

/// Validates an incoming token against the server data, allowing for clock drift. ///

public static bool ValidateToken(string seed, string pin, string providedToken, int windowSizeInSeconds = 30) { DateTime now = DateTime.UtcNow; // Account for network delay or minor device clock drift for (int i = -windowSizeInSeconds; i <= windowSizeInSeconds; i += 10) { DateTime checkTime = now.AddSeconds(i); string calculatedToken = GenerateToken(seed, pin, checkTime); if (string.Equals(calculatedToken, providedToken, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } } Use code with caution. Integrating mOTP into ASP.NET Core Identity

To integrate this engine into a modern ASP.NET Core web app or API, you can wrap the logic inside a custom TwoFactorTokenProvider.

using Microsoft.AspNetCore.Identity; using System.Threading.Tasks; public class MOtpTokenProvider : IUserTwoFactorTokenProvider where TUser : IdentityUser { public Task GenerateAsync(string purpose, UserManager manager, TUser user) { // Fetch user-specific seed and PIN from your secure data store string seed = manager.GetAuthenticationTokenAsync(user, “mOTP”, “Seed”).Result; string pin = manager.GetAuthenticationTokenAsync(user, “mOTP”, “Pin”).Result; return Task.FromResult(MOtpAuthenticator.GenerateToken(seed, pin, DateTime.UtcNow)); } public Task ValidateAsync(string purpose, string token, UserManager manager, TUser user) { string seed = manager.GetAuthenticationTokenAsync(user, “mOTP”, “Seed”).Result; string pin = manager.GetAuthenticationTokenAsync(user, “mOTP”, “Pin”).Result; return Task.FromResult(MOtpAuthenticator.ValidateToken(seed, pin, token)); } public Task CanGenerateTwoFactorTokenAsync(UserManager manager, TUser user) { // Check if the user has completed mOTP registration return Task.FromResult(user.TwoFactorEnabled); } } Use code with caution. Register the custom provider in your Program.cs file:

builder.Services.AddIdentity() .AddEntityFrameworkStores() .AddTokenProvider(“mOTP”); Use code with caution. Best Practices for Production Deployment 1. Secure Seed Storage

Never store mOTP seeds in plaintext. If an attacker gains read access to your database, they can compromise all user accounts. Encrypt seeds using a robust encryption standard like AES-256 before writing them to the database. 2. Implement Clock Drift Management

Mobile device clocks can drift out of sync with network time. The verification logic should check the current 10-second time window as well as the immediate preceding and succeeding windows to minimize false login rejections. 3. Prevent Replay Attacks

Once a token is successfully verified, flag that specific 10-second time window as “used” for that user id. Reject any subsequent validation attempts within that same window to block interception and replay attacks. Conclusion

Implementing mOTP in .NET offers an incredibly lightweight footprint for developers who want straightforward, offline, open-standard multi-factor authentication. By writing a native handler in C#, you avoid external licensing constraints while keeping full architectural control over your application’s security pipeline.

To help refine this implementation for your specific architecture, tell me: What version of .NET are you using for this project?

Do you intend to use this with an existing authentication framework (like ASP.NET Core Identity or Duende IdentityServer)?

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *