Skip to content

Pratiyush/totp-impl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
totp-lib logo

totp-lib

Security-hardened TOTP for Java

CI Maven Central Java RFC License PRs Welcome

Enterprise-grade, RFC 6238 compliant Time-based One-Time Password (TOTP) library for Java. Zero required dependencies. Constant-time verification. Replay attack prevention.

Documentation | Javadoc | Maven Central | MVN Repository

Features

  • 🔒 Security First: Constant-time verification, replay attack prevention, secure memory handling
  • 📋 RFC Compliant: Full RFC 6238 (TOTP) and RFC 4226 (HOTP) compliance
  • 🚀 Zero Dependencies: Core functionality requires no external libraries
  • High Performance: Thread-safe, stateless design for concurrent use
  • 📱 App Compatible: Works with Google Authenticator, Microsoft Authenticator, and others
  • 🧪 Well Tested: Comprehensive test suite with RFC test vectors

Quick Start

Installation

Maven:

<dependency>
    <groupId>io.github.pratiyush</groupId>
    <artifactId>totp-lib</artifactId>
    <version>1.0.3</version>
</dependency>

Gradle (Kotlin DSL):

implementation("io.github.pratiyush:totp-lib:1.0.3")

Gradle (Groovy):

implementation 'io.github.pratiyush:totp-lib:1.0.3'

Latest version: Maven Central

Basic Usage

import io.github.pratiyush.totp.Algorithm;
import io.github.pratiyush.totp.SecretGenerator;
import io.github.pratiyush.totp.TOTP;

// Generate a secret for a new user
String secret = SecretGenerator.generate(Algorithm.SHA256);

        // Create TOTP instance
        TOTP totp = TOTP.defaultInstance();

        // Generate a code (for testing/admin purposes)
        String code = totp.generate(secret);

        // Verify a code from user input
        boolean valid = totp.verify(secret, userProvidedCode);

With Replay Protection

import io.github.pratiyush.totp.TOTP;

import java.time.Duration;

// Create TOTP with replay attack prevention
TOTP totp = TOTP.builder()
        .withReplayProtection(Duration.ofMinutes(2))
        .build();

        // Verify with user ID for per-user tracking
        boolean valid = totp.verify(secret, code, userId);

Generate QR Code

import io.github.pratiyush.totp.QRCodeGenerator;

import java.nio.file.Path;

// Generate QR code for authenticator apps
QRCodeGenerator.saveToFile(
        secret, 
    "user@example.com",
            "MyApp",
        Path.of("qr.png"), 
    250
            );

// Or get as Base64 for embedding in HTML
String base64 = QRCodeGenerator.generateBase64(
        secret, "user@example.com", "MyApp", 250);
String html = "<img src='data:image/png;base64," + base64 + "'/>";

Configuration Options

Algorithm Selection

// SHA-1 (default, widest compatibility)
TOTP totp = TOTP.builder()
    .algorithm(Algorithm.SHA1)
    .build();

// SHA-256 (recommended for new implementations)
TOTP totp = TOTP.builder()
    .algorithm(Algorithm.SHA256)
    .build();

// SHA-512 (maximum security)
TOTP totp = TOTP.builder()
    .algorithm(Algorithm.SHA512)
    .build();

Custom Configuration

TOTPConfig config = TOTPConfig.builder()
    .algorithm(Algorithm.SHA256)
    .digits(8)                    // 6-8 digits
    .periodSeconds(30)            // 15-120 seconds
    .allowedDrift(1)              // Time window tolerance
    .build();

TOTP totp = TOTP.builder()
    .config(config)
    .build();

Preset Configurations

// Default (Google Authenticator compatible)
TOTPConfig.defaultConfig();

// SHA-256 with standard settings
TOTPConfig.sha256Config();

// High security (SHA-512, 8 digits)
TOTPConfig.highSecurityConfig();

Security Features

Constant-Time Verification

All code comparisons use constant-time algorithms to prevent timing attacks:

// Verification time is independent of whether the code is correct
boolean valid = totp.verify(secret, code);

Replay Attack Prevention

Prevent the same code from being used twice:

// In-memory implementation (single instance)
ReplayGuard guard = new InMemoryReplayGuard(Duration.ofMinutes(2));

// For distributed systems, implement ReplayGuard with Redis/database
public class RedisReplayGuard implements ReplayGuard {
    // Your implementation
}

Secure Memory Handling

Secrets are cleared from memory automatically:

// Internal implementation uses SecureBytes
try (SecureBytes secret = SecureBytes.wrap(secretBytes)) {
    // Use secret
} // Automatically cleared here

API Reference

TOTP

Method Description
generate(secret) Generate code for current time
generateAt(secret, instant) Generate code for specific time
verify(secret, code) Verify a code
verify(secret, code, userId) Verify with replay protection
verifyWithDetails(secret, code) Verify and get time offset
getSecondsRemaining() Seconds until current code expires
getCurrentCounter() Current TOTP counter value

SecretGenerator

Method Description
generate() Generate 160-bit secret
generate(algorithm) Generate algorithm-appropriate secret
generate(lengthBytes) Generate custom length secret
isValid(secret) Validate a secret

QRCodeGenerator

Method Description
generateImage(...) Generate BufferedImage
generateBase64(...) Generate Base64 PNG
generateDataUri(...) Generate data URI
saveToFile(...) Save to file
buildOtpauthUri(...) Build otpauth:// URI

Algorithm Recommendations

Algorithm Key Size Use Case
SHA-1 20 bytes Legacy compatibility
SHA-256 32 bytes Recommended for new apps
SHA-512 64 bytes Maximum security requirements

Building

# Compile and run tests
mvn clean verify

# Generate coverage report
mvn jacoco:report

# Build uber-JAR with all dependencies
mvn package -Pshade

Requirements

  • Java 21 or higher
  • Maven 3.6+ (for building)

Dependencies

Dependency Scope Purpose
jSpecify Required Null safety annotations
ZXing (com.google.zxing) Optional QR code generation
SLF4J Optional Logging

Null Safety

This library uses jSpecify annotations for null safety:

  • @NullMarked at package level (all types non-null by default)
  • @Nullable to mark nullable parameters and return types

Compatible with tools like NullAway, Error Prone, and IntelliJ IDEA.

Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines and coding standards.

This project follows the Contributor Covenant code of conduct.

License

MIT License - see LICENSE for details.

References

About

Java Implementation of TOTP (Time-based one-time password)

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages