pub struct TotpGenerator;Expand description
TOTP Generator for Two-Factor Authentication
Provides cryptographic functions for TOTP secret generation, QR code creation, code verification, backup code management, and AES-256-GCM encryption.
§Security Features
- TOTP Secret: 32-byte random Base32-encoded secret (RFC 4648)
- QR Code: otpauth:// URI format for authenticator apps
- Backup Codes: 10 secure random 8-character alphanumeric codes
- Encryption: AES-256-GCM authenticated encryption for secrets
- Hashing: bcrypt (cost factor 12) for backup codes
- Time Window: ±30 seconds tolerance for clock skew (±1 step)
Implementations§
Source§impl TotpGenerator
impl TotpGenerator
Sourcepub fn generate_secret() -> String
pub fn generate_secret() -> String
Generate a random TOTP secret (Base32-encoded, 32 bytes)
Returns a 52-character Base32 string suitable for TOTP generation.
§Example
let secret = TotpGenerator::generate_secret();
assert_eq!(secret.len(), 52); // Base32 encoding of 32 bytesSourcepub fn generate_qr_code(
secret: &str,
issuer: &str,
account_name: &str,
) -> Result<String, String>
pub fn generate_qr_code( secret: &str, issuer: &str, account_name: &str, ) -> Result<String, String>
Generate QR code data URL for authenticator apps
Creates an otpauth://totp/ URI and encodes it as a PNG QR code data URL.
§Arguments
secret- Base32-encoded TOTP secretissuer- Service name (e.g., “KoproGo”)account_name- User identifier (e.g., email address)
§Returns
Base64-encoded PNG image data URL: data:image/png;base64,...
§Errors
Returns error if QR code generation or image encoding fails.
Sourcepub fn verify_code(secret: &str, code: &str) -> Result<bool, String>
pub fn verify_code(secret: &str, code: &str) -> Result<bool, String>
Verify TOTP code with ±1 time window tolerance
Validates a 6-digit TOTP code against the secret with 30-second time steps. Accepts codes from current step, previous step (t-30s), and next step (t+30s).
§Arguments
secret- Base32-encoded TOTP secret (unencrypted)code- 6-digit TOTP code to verify
§Returns
Ok(true) if code is valid, Ok(false) if invalid format/value
§Example
let secret = TotpGenerator::generate_secret();
let code = TotpGenerator::generate_current_code(&secret)?;
assert!(TotpGenerator::verify_code(&secret, &code)?);Sourcepub fn generate_backup_codes() -> Vec<String>
pub fn generate_backup_codes() -> Vec<String>
Generate 10 secure random backup codes (8 characters each)
Each code is in format XXXX-XXXX with uppercase alphanumeric characters
(excluding ambiguous chars: 0, O, 1, I, L).
§Returns
Vector of 10 unique backup codes
§Example
let codes = TotpGenerator::generate_backup_codes();
assert_eq!(codes.len(), 10);
assert!(codes[0].len() == 9); // "XXXX-XXXX"Sourcepub fn encrypt_secret(secret: &str, key: &[u8; 32]) -> Result<String, String>
pub fn encrypt_secret(secret: &str, key: &[u8; 32]) -> Result<String, String>
Encrypt TOTP secret using AES-256-GCM
§Arguments
secret- Plain text Base32 secretkey- 32-byte AES-256 key (from environment variable)
§Returns
Base64-encoded ciphertext with prepended nonce (12 bytes + ciphertext)
§Security
- Uses AES-256-GCM for authenticated encryption
- Random 96-bit nonce per encryption
- Authenticated with GMAC tag
§Errors
Returns error if encryption fails or key is invalid
Auto Trait Implementations§
impl Freeze for TotpGenerator
impl RefUnwindSafe for TotpGenerator
impl Send for TotpGenerator
impl Sync for TotpGenerator
impl Unpin for TotpGenerator
impl UnwindSafe for TotpGenerator
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Chain<T> for T
impl<T> Chain<T> for T
§impl<T> Fake for T
impl<T> Fake for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more