### Complete 2FA Enrollment and Validation Flow Source: https://context7.com/pquerna/otp/llms.txt This Go program demonstrates a full two-factor authentication process, including user enrollment, QR code generation, enrollment confirmation, and login validation using TOTP. ```go package main import ( "bytes" "fmt" "image/png" "os" "time" "github.com/pquerna/otp" "github.com/pquerna/otp/totp" ) // User represents a user in your system type User struct { Email string TOTPSecret string } // Database simulation var userDB = make(map[string]*User) // EnrollUser creates a new TOTP key for a user and returns QR code data func EnrollUser(email string) (qrCodePNG []byte, secret string, err error) { key, err := totp.Generate(totp.GenerateOpts{ Issuer: "MySecureApp", AccountName: email, Period: 30, SecretSize: 20, Digits: otp.DigitsSix, Algorithm: otp.AlgorithmSHA1, }) if err != nil { return nil, "", err } // Generate QR code img, err := key.Image(200, 200) if err != nil { return nil, "", err } var buf bytes.Buffer if err := png.Encode(&buf, img); err != nil { return nil, "", err } return buf.Bytes(), key.Secret(), nil } // ConfirmEnrollment verifies the user can generate valid codes before saving func ConfirmEnrollment(email, secret, passcode string) bool { if totp.Validate(passcode, secret) { // Save to database only after successful validation userDB[email] = &User{Email: email, TOTPSecret: secret} return true } return false } // ValidateLogin checks a TOTP code during login func ValidateLogin(email, passcode string) bool { user, exists := userDB[email] if !exists { return false } return totp.Validate(passcode, user.TOTPSecret) } func main() { email := "alice@example.com" // Step 1: Generate enrollment data qrPNG, secret, err := EnrollUser(email) if err != nil { panic(err) } // Save QR code for user to scan os.WriteFile("enrollment-qr.png", qrPNG, 0644) fmt.Printf("Enrollment QR saved. Secret: %s\n", secret) // Step 2: User scans QR and enters code to confirm // Simulate user entering a valid code testCode, _ := totp.GenerateCode(secret, time.Now()) if ConfirmEnrollment(email, secret, testCode) { fmt.Println("2FA enrollment confirmed!") } // Step 3: During login, validate the TOTP loginCode, _ := totp.GenerateCode(secret, time.Now()) if ValidateLogin(email, loginCode) { fmt.Println("Login successful with 2FA!") } else { fmt.Println("Invalid 2FA code!") } } ``` -------------------------------- ### Generate and Validate HOTP Codes Source: https://context7.com/pquerna/otp/llms.txt Demonstrates generating HOTP codes and validating them. Remember to increment the counter after each successful validation. ```go package main import ( "fmt" "github.com/pquerna/otp" "github.com/pquerna/otp/hotp" ) func main() { secret := "JBSWY3DPEHPK3PXP" var counter uint64 = 0 // Generate HOTP code for counter value code, err := hotp.GenerateCode(secret, counter) if err != nil { panic(err) } fmt.Printf("HOTP code for counter %d: %s\n", counter, code) // Validate the code valid := hotp.Validate(code, counter, secret) if valid { fmt.Println("Valid! Increment counter for next use.") counter++ // Important: increment counter after successful validation } // Generate next code nextCode, _ := hotp.GenerateCode(secret, counter) fmt.Printf("HOTP code for counter %d: %s\n", counter, nextCode) // Validate with custom options code8Digit, err := hotp.GenerateCodeCustom(secret, counter, hotp.ValidateOpts{ Digits: otp.DigitsEight, Algorithm: otp.AlgorithmSHA256, }) if err != nil { panic(err) } fmt.Printf("8-digit HOTP code: %s\n", code8Digit) valid, err = hotp.ValidateCustom(code8Digit, counter, secret, hotp.ValidateOpts{ Digits: otp.DigitsEight, Algorithm: otp.AlgorithmSHA256, }) if err != nil { fmt.Printf("Error: %v\n", err) } fmt.Printf("Custom validation result: %v\n", valid) } ``` -------------------------------- ### Generate TOTP Key for User Enrollment Source: https://context7.com/pquerna/otp/llms.txt Use `totp.Generate` to create a new TOTP key. This function returns a Key object containing the secret and a URL suitable for QR code generation, facilitating user enrollment in authenticator apps. Store the secret for later validation. ```go package main import ( "bytes" "fmt" "image/png" "os" "github.com/pquerna/otp" "github.com/pquerna/otp/totp" ) func main() { // Generate a new TOTP key for the user key, err := totp.Generate(totp.GenerateOpts{ Issuer: "Example.com", AccountName: "alice@example.com", }) if err != nil { panic(err) } // Access key information fmt.Printf("Issuer: %s\n", key.Issuer()) // Output: Example.com fmt.Printf("Account Name: %s\n", key.AccountName()) // Output: alice@example.com fmt.Printf("Secret: %s\n", key.Secret()) // Output: Base32 encoded secret fmt.Printf("URL: %s\n", key.URL()) // Output: otpauth://totp/... // Generate QR code image for authenticator app enrollment img, err := key.Image(200, 200) if err != nil { panic(err) } // Save QR code as PNG file var buf bytes.Buffer png.Encode(&buf, img) os.WriteFile("qr-code.png", buf.Bytes(), 0644) // Store key.Secret() in your database for later validation fmt.Println("Store this secret for the user:", key.Secret()) } ``` -------------------------------- ### Implement Steam Guard Support Source: https://context7.com/pquerna/otp/llms.txt Uses the EncoderSteam option to handle Steam's specific alphanumeric code format. ```go package main import ( "fmt" "time" "github.com/pquerna/otp" "github.com/pquerna/otp/totp" ) func main() { // Parse Steam Guard URL steamURL := "otpauth://totp/username%20steam:username?secret=qlt6vmy6svfx4bt4rpmisaiyol6hihca&period=30&digits=5&issuer=username%20steam&encoder=steam" key, err := otp.NewKeyFromURL(steamURL) if err != nil { panic(err) } fmt.Printf("Secret: %s\n", key.Secret()) fmt.Printf("Encoder: %v\n", key.Encoder()) // Output: steam fmt.Printf("Digits: %d\n", key.Digits()) // Output: 5 // Generate Steam Guard code opts := totp.ValidateOpts{ Period: uint(key.Period()), Digits: key.Digits(), Encoder: key.Encoder(), } code, err := totp.GenerateCodeCustom(key.Secret(), time.Now().UTC(), opts) if err != nil { panic(err) } fmt.Printf("Steam Guard Code: %s\n", code) // Output: 5-character alphanumeric code // Validate Steam Guard code valid, err := totp.ValidateCustom(code, key.Secret(), time.Now().UTC(), opts) if err != nil { panic(err) } fmt.Printf("Valid: %v\n", valid) } ``` -------------------------------- ### Generate TOTP Key with Custom Options Source: https://context7.com/pquerna/otp/llms.txt Customize TOTP key generation using `totp.GenerateOpts` to specify parameters like period, secret size, digit count, and hash algorithm. You can also provide a pre-defined secret. ```go package main import ( "fmt" "github.com/pquerna/otp" "github.com/pquerna/otp/totp" ) func main() { // Generate TOTP key with custom options key, err := totp.Generate(totp.GenerateOpts{ Issuer: "MyApp", AccountName: "user@myapp.com", Period: 30, // Rotation period in seconds (default: 30) SecretSize: 20, // Secret size in bytes (default: 20) Digits: otp.DigitsSix, // Number of digits: DigitsSix or DigitsEight Algorithm: otp.AlgorithmSHA1, // SHA1, SHA256, SHA512, or MD5 }) if err != nil { panic(err) } fmt.Printf("Type: %s\n", key.Type()) // Output: totp fmt.Printf("Period: %d\n", key.Period()) // Output: 30 fmt.Printf("Digits: %d\n", key.Digits()) // Output: 6 fmt.Printf("Algorithm: %s\n", key.Algorithm()) // Output: SHA1 // Generate with a pre-defined secret (useful for testing or migration) keyWithSecret, err := totp.Generate(totp.GenerateOpts{ Issuer: "MyApp", AccountName: "user@myapp.com", Secret: []byte("helloworld"), // Use a specific secret }) if err != nil { panic(err) } fmt.Printf("Predefined Secret: %s\n", keyWithSecret.Secret()) } ``` -------------------------------- ### Parse OTP URLs Source: https://context7.com/pquerna/otp/llms.txt Parses otpauth:// URLs into Key objects to extract configuration details like secret, issuer, and algorithm. ```go package main import ( "fmt" "github.com/pquerna/otp" ) func main() { // Parse a TOTP URL (common format from QR codes) totpURL := "otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example&algorithm=sha256&digits=8" key, err := otp.NewKeyFromURL(totpURL) if err != nil { panic(err) } // Extract all key information fmt.Printf("Type: %s\n", key.Type()) // Output: totp fmt.Printf("Issuer: %s\n", key.Issuer()) // Output: Example fmt.Printf("Account Name: %s\n", key.AccountName()) // Output: alice@google.com fmt.Printf("Secret: %s\n", key.Secret()) // Output: JBSWY3DPEHPK3PXP fmt.Printf("Algorithm: %s\n", key.Algorithm()) // Output: SHA256 fmt.Printf("Digits: %d\n", key.Digits()) // Output: 8 fmt.Printf("Period: %d\n", key.Period()) // Output: 30 (default) // Parse HOTP URL hotpURL := "otpauth://hotp/MyApp:user@example.com?secret=GEZDGNBVGY3TQOJQ&issuer=MyApp&counter=0" hotpKey, _ := otp.NewKeyFromURL(hotpURL) fmt.Printf("\nHOTP Type: %s\n", hotpKey.Type()) // Output: hotp // Parse Google-generated URL (may have lowercase secret) googleURL := "otpauth://totp/Google%3Afoo%40example.com?secret=qlt6vmy6svfx4bt4rpmisaiyol6hihca&issuer=Google" googleKey, _ := otp.NewKeyFromURL(googleURL) fmt.Printf("\nGoogle Secret: %s\n", googleKey.Secret()) // lowercase is handled automatically } ``` -------------------------------- ### Validate TOTP with Custom Options in Go Source: https://context7.com/pquerna/otp/llms.txt Use ValidateCustom to verify passcodes with specific time, period, skew, and algorithm settings. Supports both SHA1 and SHA256 algorithms. ```go package main import ( "fmt" "time" "github.com/pquerna/otp" "github.com/pquerna/otp/totp" ) func main() { secret := "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ" // base32 encoded secret passcode := "94287082" // Validate with custom options valid, err := totp.ValidateCustom(passcode, secret, time.Unix(59, 0).UTC(), totp.ValidateOpts{ Period: 30, // Time period in seconds Skew: 1, // Allow 1 period before/after (clock drift tolerance) Digits: otp.DigitsEight, // Expect 8-digit codes Algorithm: otp.AlgorithmSHA1, // Hash algorithm }) if err != nil { fmt.Printf("Validation error: %v\n", err) return } if valid { fmt.Println("Valid passcode!") } else { fmt.Println("Invalid passcode!") } // Example with SHA256 algorithm secretSha256 := "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZA" passcodeSha256 := "46119246" valid, _ = totp.ValidateCustom(passcodeSha256, secretSha256, time.Unix(59, 0).UTC(), totp.ValidateOpts{ Period: 30, Skew: 1, Digits: otp.DigitsEight, Algorithm: otp.AlgorithmSHA256, }) fmt.Printf("SHA256 validation: %v\n", valid) } ``` -------------------------------- ### Generate HOTP Keys in Go Source: https://context7.com/pquerna/otp/llms.txt Create HMAC-based One-Time Password keys using hotp.Generate. Supports custom secret sizes, digit counts, and algorithms. ```go package main import ( "fmt" "github.com/pquerna/otp" "github.com/pquerna/otp/hotp" ) func main() { // Generate a new HOTP key key, err := hotp.Generate(hotp.GenerateOpts{ Issuer: "MyApp", AccountName: "user@example.com", }) if err != nil { panic(err) } fmt.Printf("Type: %s\n", key.Type()) // Output: hotp fmt.Printf("Issuer: %s\n", key.Issuer()) fmt.Printf("Account Name: %s\n", key.AccountName()) fmt.Printf("Secret: %s\n", key.Secret()) fmt.Printf("URL: %s\n", key.URL()) // Generate with custom options keyCustom, err := hotp.Generate(hotp.GenerateOpts{ Issuer: "SecureApp", AccountName: "admin@secure.com", SecretSize: 20, // Secret size in bytes (default: 10) Digits: otp.DigitsEight, // 8-digit codes Algorithm: otp.AlgorithmSHA256, // Use SHA256 }) if err != nil { panic(err) } fmt.Printf("Custom HOTP URL: %s\n", keyCustom.URL()) } ``` -------------------------------- ### Steam Guard Support Source: https://context7.com/pquerna/otp/llms.txt Handling Steam Guard specific OTP configurations and alphanumeric code generation. ```APIDOC ## Steam Guard OTP ### Description Supports Steam Guard's custom alphanumeric encoding format by utilizing the `EncoderSteam` option within TOTP validation and generation. ### Usage - Use `otp.NewKeyFromURL` to parse the Steam URL. - Pass the `key.Encoder()` into `totp.ValidateOpts`. - Use `totp.GenerateCodeCustom` or `totp.ValidateCustom` with the configured options. ``` -------------------------------- ### Parsing OTP URLs Source: https://context7.com/pquerna/otp/llms.txt Utility to parse otpauth:// URLs into structured Key objects. ```APIDOC ## otp.NewKeyFromURL ### Description Parses an otpauth:// URL (commonly used in QR codes) into a Key object to extract configuration details. ### Method `otp.NewKeyFromURL(url string)` ### Parameters - **url** (string) - Required - The full otpauth URL string. ### Response - **Key Object** - Contains methods: Type(), Issuer(), AccountName(), Secret(), Algorithm(), Digits(), Period(), and Encoder(). ``` -------------------------------- ### Generate TOTP Codes in Go Source: https://context7.com/pquerna/otp/llms.txt Generate TOTP codes using default or custom settings. Ensure UTF-8 secrets are base32 encoded before generation. ```go package main import ( "encoding/base32" "fmt" "time" "github.com/pquerna/otp" "github.com/pquerna/otp/totp" ) func main() { secret := "JBSWY3DPEHPK3PXP" // Generate code using current time with defaults code, err := totp.GenerateCode(secret, time.Now()) if err != nil { panic(err) } fmt.Printf("Generated TOTP code: %s\n", code) // Generate code with custom options codeCustom, err := totp.GenerateCodeCustom(secret, time.Now(), totp.ValidateOpts{ Period: 30, Digits: otp.DigitsSix, Algorithm: otp.AlgorithmSHA1, }) if err != nil { panic(err) } fmt.Printf("Generated custom TOTP code: %s\n", codeCustom) // Generate code from UTF-8 string secret (encode to base32 first) utf8Secret := "mysecretkey12345" base32Secret := base32.StdEncoding.EncodeToString([]byte(utf8Secret)) codeFromUtf8, err := totp.GenerateCodeCustom(base32Secret, time.Now(), totp.ValidateOpts{ Period: 30, Skew: 1, Digits: otp.DigitsSix, Algorithm: otp.AlgorithmSHA512, }) if err != nil { panic(err) } fmt.Printf("Generated code from UTF-8 secret: %s\n", codeFromUtf8) } ``` -------------------------------- ### HOTP Validation and Code Generation Source: https://context7.com/pquerna/otp/llms.txt Functions for generating and validating counter-based OTP codes, including support for custom digit lengths and algorithms. ```APIDOC ## HOTP Generation and Validation ### Description Generates and validates counter-based OTP codes. Note that the counter must be manually incremented after a successful validation. ### Methods - `hotp.GenerateCode(secret string, counter uint64)` - `hotp.Validate(code string, counter uint64, secret string)` - `hotp.GenerateCodeCustom(secret string, counter uint64, opts ValidateOpts)` - `hotp.ValidateCustom(code string, counter uint64, secret string, opts ValidateOpts)` ### Parameters - **secret** (string) - Required - The shared secret key. - **counter** (uint64) - Required - The current counter value. - **opts** (ValidateOpts) - Optional - Configuration for digits and algorithm (e.g., SHA256, 8-digits). ``` -------------------------------- ### Validate TOTP Passcode Source: https://context7.com/pquerna/otp/llms.txt Use `totp.Validate` to verify a user-entered passcode against their stored secret. This function uses default Google Authenticator settings (30-second period, 6 digits, SHA1) and automatically considers a time skew of 1. ```go package main import ( "fmt" "github.com/pquerna/otp/totp" ) func main() { // User's stored secret (retrieved from database) secret := "JBSWY3DPEHPK3PXP" // Passcode entered by user passcode := "123456" // Validate the passcode - uses current time automatically valid := totp.Validate(passcode, secret) if valid { fmt.Println("Valid passcode! User authenticated.") } else { fmt.Println("Invalid passcode! Authentication failed.") } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.