kd_totp
Time-based One-Time Password (TOTP) 2FA implementation per RFC 6238 and RFC 4226.
Features
- RFC 6238 (TOTP) and RFC 4226 (HOTP) compliant
- Two-step enrollment: setup → confirm → enable
- Replay attack prevention with counter tracking
- Configurable clock drift tolerance
- QR code URI generation (Google Authenticator compatible)
- Timing-safe code comparison
- PostgreSQL and SQLite support
Installation
dependencies:
kd_totp: ^1.0.0Usage
Low-Level Algorithm
import 'package:kd_totp/kd_totp.dart';
// Generate a secret
final secret = TotpAlgorithm.generateSecret();
// Generate a TOTP code
final code = TotpAlgorithm.totp(secret);
// Verify a code
final result = TotpAlgorithm.verify(secret, code);
if (result != null) {
print('Valid! Delta: $result');
}
// Generate a QR code URI
final uri = TotpAlgorithm.generateUri(
secret: secret,
accountName: 'user@example.com',
issuer: 'MyApp',
);Service Layer
final totpService = TotpService(
repository: SqliteTotpRepository(db),
config: TotpConfig(
timeStep: 30,
digits: 6,
window: 1,
),
);Enrollment Flow
// Step 1: Generate secret and create pending entry
final secret = totpService.generateSecret();
final uri = totpService.generateUri(
secret: secret,
accountName: 'user@example.com',
issuer: 'MyApp',
);
// Display URI as QR code to user
await totpService.setupTotp(
accountId: accountId,
secret: secret,
);
// Step 2: User scans QR code and enters confirmation code
await totpService.enableTotp(
accountId: accountId,
confirmationCode: '123456',
);Login Verification
// Verify and consume code (prevents replay attacks)
await totpService.verifyAndConsume(
accountId: accountId,
code: '654321',
);Configuration
| Option | Default | Description |
|---|---|---|
| timeStep | 30 | TOTP time step in seconds |
| digits | 6 | Number of digits in the code |
| window | 1 | Clock drift tolerance |