otpverifier

package
v0.10.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 1, 2024 License: BSD-3-Clause Imports: 32 Imported by: 0

Documentation

Overview

Package otpverifier provides a simple and flexible way to verify and generate one-time passwords (OTPs) using time-based (TOTP) or counter-based (HOTP) algorithms. It supports optional signature generation and verification for enhanced security.

The package offers an otpverifier.OTPVerifier interface that defines the behavior of an OTP verifier. It includes methods for verifying tokens and signatures and generating tokens and signatures.

The package provides two implementations of the otpverifier.OTPVerifier interface: otpverifier.TOTPVerifier and otpverifier.HOTPVerifier. otpverifier.TOTPVerifier is used for time-based OTPs, while otpverifier.HOTPVerifier is used for counter-based OTPs.

The package also includes an otpverifier.OTPFactory function that creates an appropriate otpverifier.OTPVerifier based on the provided configuration. The configuration is defined using the Config struct, which holds options such as the secret key, counter value, signature usage, and time source.

Example usage:

// Create a configuration for TOTP
totpConfig := otpverifier.Config{
	Secret:       "your-secret-key",
	UseSignature: true,
}

// Create a TOTP verifier using the factory function
totpVerifier := otpverifier.OTPFactory(totpConfig)

// Generate a token and signature
token, signature := totpVerifier.GenerateToken()

// Verify the token and signature
isValid := totpVerifier.Verify(token, signature)

// Create a configuration for HOTP
hotpConfig := otpverifier.Config{
	Secret:       "your-secret-key",
	Counter:      1000,
	UseSignature: true,
}

// Create an HOTP verifier using the factory function
hotpVerifier := otpverifier.OTPFactory(hotpConfig)

// Generate a token and signature
token, signature := hotpVerifier.GenerateToken()

// Verify the token and signature
isValid := hotpVerifier.Verify(token, signature)

Example usage with custom time zone (Antarctica):

// Custom time source function for Antarctica time zone
antarcticaTimeSource := func() time.Time {
	location, _ := time.LoadLocation("Antarctica/South_Pole")
	return time.Now().In(location)
}

// Create a configuration for TOTP with custom time source
totpConfig := otpverifier.Config{
	Secret:       "your-secret-key",
	UseSignature: true,
	TimeSource:   antarcticaTimeSource,
}

// Create a TOTP verifier using the factory function
totpVerifier := otpverifier.OTPFactory(totpConfig)

// Generate a token and signature using Antarctica time zone
token, signature := totpVerifier.GenerateToken()

// Verify the token and signature using Antarctica time zone
isValid := totpVerifier.Verify(token, signature)

The package uses the github.com/xlzd/gotp library for generating and verifying OTPs, and the crypto/hmac, crypto/sha256, crypto/sha512, github.com/H0llyW00dzZ/fiber2fa/internal/crypto/hash/blake2botp, and github.com/H0llyW00dzZ/fiber2fa/internal/crypto/hash/blake3otp packages for generating and verifying signatures using HMAC with SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256, BLAKE2b, and BLAKE3.

Configuration

The OTP verifier can be configured using the otpverifier.Config struct. The available options are:

  • Secret: The shared secret key used for generating and verifying OTPs. This field is required.
  • Digits: The number of digits in the generated OTP. Default is 6.
  • Period: The time step size in seconds for TOTP. Default is 30 seconds.
  • UseSignature: Determines whether to generate and verify signatures. Default is false.
  • TimeSource: The time source function used for TOTP. This field is required. The time source function should return
  • Counter: The initial counter value for HOTP. Default is to use Config.GenerateSecureRandomCounter with the default number of digits specified in otpverifier.DefaultConfig.Digits.
  • CounterMismatch: The counter mismatch threshold for adjusting the synchronization window size. Available options are:
  • CounterMismatchThreshold1x: Adjust the sync window size if the counter mismatch exceeds 1.
  • CounterMismatchThreshold3x: Adjust the sync window size if the counter mismatch exceeds 3.
  • CounterMismatchThreshold5x: Adjust the sync window size if the counter mismatch exceeds 5.
  • SyncWindow: The number of time steps (for TOTP) or counter values (for HOTP) to check before and after the current value when verifying OTPs. The synchronization window size can be adjusted based on the counter mismatch threshold. Available options are:
  • NoneStrict: No strictness, the synchronization window size is not enforced.
  • HighStrict: Highest strictness, the synchronization window size is fixed at 1.
  • MediumStrict: Medium strictness, the synchronization window size is determined by the corresponding range in SyncWindowRanges.
  • LowStrict: Low strictness, the synchronization window size is determined by the corresponding range in SyncWindowRanges.
  • ResyncWindowDelay: The delay duration for resynchronizing the synchronization window. Default is 30 minutes.
  • URITemplate: The URI template used for generating OTP URLs. Default is "otpauth://%s/%s:%s?secret=%s&issuer=%s&digits=%d&algorithm=%s".
  • CustomURITemplateParams (Advanced Cryptographic OTP Use Cases, e.g., Customize Character Set instead of numbers in client device, callback to the server, etc.): A map of custom parameters to include in the OTP URL. Default is nil.
  • Hash: The name of the hashing algorithm to use. This field is required. List values are:
  • SHA1
  • SHA224
  • SHA256
  • SHA384
  • SHA512
  • SHA512S224
  • SHA512S256
  • BLAKE2b256
  • BLAKE2b384
  • BLAKE2b512
  • BLAKE3256
  • BLAKE3384
  • BLAKE3512
  • CleanupIntervals: The interval at which the cleanup process runs to remove expired tokens in the TOTP verifier. Available options are:
  • FastCleanup
  • MediumCleanup
  • SlowCleanup

QR Code Configuration

The QR code generation can be configured using the otpverifier.QRCodeConfig struct. The available options are:

  • Level: The error correction level for the QR code. Default is qrcode.Medium.
  • Size: The size of the QR code image in pixels. Default is 256.
  • ForegroundColor: The color of the QR code foreground. Default is color.Black.
  • BackgroundColor: The color of the QR code background. Default is color.White.
  • DisableBorder: Determines whether to disable the QR code border. Default is false.
  • TopText: The text to display above the QR code. Default is an empty string.
  • BottomText: The text to display below the QR code. Default is an empty string.
  • Font: The font to use for the top and bottom text. Default is basicfont.Face7x13.
  • TopTextPosition: The position of the top text. Default is calculated dynamically.
  • BottomTextPosition: The position of the bottom text. Default is calculated dynamically.
  • FilePath: The file path where the QR code image will be saved. Default is an empty string.

The default QR code configuration can be accessed using DefaultQRCodeConfig.

Compatible and Supported Devices

This package aims to provide compatibility with a wide range of devices and 2FA apps. However, it's important to note that not all 2FA apps, especially mobile apps, are fully supported by this package. The reasons for this include:

  1. Poor Ecosystems: Some mobile 2FA apps have limited support for certain hashing algorithms, such as SHA-512/224, SHA-512/256, BLAKE2b, and BLAKE3. These apps may not be able to generate or verify tokens using these algorithms.

  2. Incorrect Entropy in Token Generation: This issue is more prevalent with HOTP when setting the counter to a random value for initialization (e.g, use Config.GenerateSecureRandomCounter to generate a secure random counter value). Some 2FA apps may generate tokens using a different entropy source or algorithm, which literally breaks the cryptographic principles related to hash functions. This can lead to incompatibility with the tokens generated by this package. For example, while some 2FA apps may be able to generate tokens, when verified using this package, they may be considered "invalid".

  3. Time Synchronization Issues (for TOTP): TOTP relies on a synchronized time value between the server and the client. If the client's device has an incorrect time or if there are significant delays in communication, it can cause issues with token verification. This is because this package uses crypto/subtle, which provides strict and strong synchronization requirements related to time to prevent brute-force and timing attacks. As a result, even small discrepancies in time synchronization can lead to token verification failures.

  4. MFA Not Supported: Multi-Factor Authentication (MFA) is not supported within this package due to the high risks associated with it. MFA often relies on hash functions like MD5, SHA-1, SHA-256, or SHA-512, which are basically the same. However, the use cases for MFA are not guaranteed since it is linked to many sensitive data points, such as user accounts, unlike 2FA (e.g., TOTP) which is typically used for a specific purpose.

To ensure the best compatibility and support, consider the following recommendations:

  • Use widely supported hashing algorithms, such as SHA-1, SHA-256, or SHA-512, when configuring the package.
  • For HOTP, consider starting the counter from a well-known value (e.g., 1) and incrementing it consistently on both the server and the client side. Alternatively, use Config.GenerateSecureRandomCounter to generate a secure random counter value.
  • Set the correct time synchronization to ensure that the server and client (e.g., mobile devices or other devices) have the same time reference. This minimizes time-related issues with TOTP and ensures accurate token verification. It is important to use Unix time (POSIX time/Epoch time) with a 64-bit integer for time synchronization to maintain compatibility and avoid issues related to time zones and daylight saving time.
  • If using less common hashing algorithms or advanced features, consider building custom 2FA mobile apps to ensure full compatibility with the package.

By following these guidelines and being aware of the potential limitations, it is possible to maximize the compatibility and support for various devices and 2FA apps when using this package.

Synchronization and Resynchronization for HOTP

This package provides standard basic mathematical synchronization and resynchronization mechanisms for HOTP (HMAC-based One-Time Password) to achieve a perfect balance between server, client, security, and system. The synchronization and resynchronization features are designed to handle scenarios where the server and client counters may become out of sync.

  1. Synchronization

Synchronization in HOTP refers to the process of ensuring that the server and client counters are in sync. The package uses a synchronization window (otpverifier.SyncWindow) to allow for a certain degree of tolerance when verifying HOTP tokens. The synchronization window determines the number of counter values to check before and after the current server counter value.

The synchronization window size can be configured using the otpverifier.SyncWindow field in the Config struct. The available options are:

  • NoneStrict: No strictness, the synchronization window size is not enforced.
  • HighStrict: Highest strictness, the synchronization window size is fixed at 1.
  • MediumStrict: Medium strictness, the synchronization window size is determined by the corresponding range in SyncWindowRanges.
  • LowStrict: Low strictness, the synchronization window size is determined by the corresponding range in SyncWindowRanges.

The SyncWindowRanges map defines the ranges of synchronization window sizes for different strictness levels. For example, MediumStrict corresponds to a range of 2 to 5, while LowStrict corresponds to a range of 5 to 10.

During the HOTP token verification process, the package checks the provided token against the server counter value and the counter values within the synchronization window. If a match is found, the token is considered valid, and the server counter is updated to the next expected value.

  1. Resynchronization

Resynchronization in HOTP is the process of automatically adjusting the server counter value when it becomes significantly out of sync with the client counter. The package implements a resynchronization mechanism based on the number of counter mismatches.

The resynchronization behavior can be configured using the otpverifier.CounterMismatch field in the Config struct. The available options are:

When the number of counter mismatches exceeds the configured threshold, the package automatically adjusts the synchronization window size based on the otpverifier.SyncWindow configuration. This adjustment helps to accommodate larger discrepancies between the server and client counters.

The resynchronization process is triggered after a specified delay (otpverifier.ResyncWindowDelay) to prevent excessive adjustments. The default delay is 30 minutes, but it can be customized in the Config struct.

By providing synchronization and resynchronization mechanisms, this package aims to maintain a balanced and secure HOTP implementation that can handle various scenarios of counter mismatches between the server and client.

Synchronization for TOTP

This package provides a synchronization mechanism for TOTP (Time-based One-Time Password) to handle scenarios where the server and client clocks may be slightly out of sync. The synchronization feature is designed to accommodate minor time differences while maintaining the security of the TOTP verification process.

  1. Synchronization Window

Synchronization in TOTP refers to the process of allowing a certain degree of tolerance when verifying TOTP tokens. The package uses a synchronization window (otpverifier.SyncWindow) to account for small time differences between the server and client clocks.

The synchronization window determines the number of time steps before and after the current time step to consider when verifying a TOTP token. It allows for a token to be valid within a specific range of time steps, rather than requiring an exact match.

The synchronization window size can be configured using the otpverifier.SyncWindow field in the Config struct. It accepts an integer value representing the number of time steps to include in the synchronization window.

For example, if the synchronization window size is set to 1, the package will consider tokens valid within a range of ±1 time step from the current time step. If the synchronization window size is set to 2, the range will be ±2 time steps, and so on.

The appropriate synchronization window size depends on the specific requirements of your application and the expected time drift between the server and client clocks. A larger synchronization window allows for greater tolerance but may also increase the window of opportunity for token reuse.

It's important to strike a balance between usability and security when determining the synchronization window size. A smaller window size provides stricter security but may lead to more frequent token rejections due to clock drift. Conversely, a larger window size accommodates more significant time differences but may weaken the security guarantees.

  1. Time Source and Period

The synchronization mechanism in TOTP relies on a synchronized time source between the server and client. The package requires you to specify a time source function (otpverifier.Config.TimeSource) to ensure accurate time synchronization.

The time source function should return the current time in the desired location or time zone. It is the responsibility of the user to provide a suitable time source function that meets their specific requirements.

In addition to the time source, the TOTP verification process also depends on the time step size, known as the period (otpverifier.Config.Period). The period determines the duration of each time step in seconds. The default period is 30 seconds, as specified in the TOTP standard (RFC 6238).

It's important to note that the synchronization window and the period are closely related. The synchronization window size is expressed in terms of the number of time steps, while the period determines the actual duration of each time step.

For example, if the period is set to 30 seconds and the synchronization window size is set to 1, the package will consider tokens valid within a range of ±30 seconds from the current time.

By providing a synchronization mechanism for TOTP, this package aims to accommodate minor time differences between the server and client clocks while maintaining the security and integrity of the TOTP verification process. It allows for a configurable degree of tolerance, ensuring that valid tokens are accepted even in the presence of slight time discrepancies.

Note: The synchronization mechanism for TOTP is not explicitly defined in the TOTP standard (RFC 6238). It is an additional feature provided by this package to enhance the usability and reliability of TOTP implementations. The effectiveness of the synchronization depends on the accuracy of the time source and the appropriate configuration of the synchronization window and period.

Index

Constants

View Source
const (
	// SHA1 represents the SHA-1 hash function.
	// SHA-1 produces a 160-bit (20-byte) hash value.
	// It is considered less secure compared to newer variants due to potential vulnerabilities.
	SHA1 = "SHA1"

	// SHA224 represents the SHA-224 hash function.
	// SHA-224 produces a 224-bit (28-byte) hash value.
	// It is a truncated version of SHA-256 and provides a balance between security and performance.
	//
	// Note: Some 2FA mobile apps might not support SHA-224 due to poor ecosystem.
	SHA224 = "SHA224"

	// SHA256 represents the SHA-256 hash function.
	// SHA-256 produces a 256-bit (32-byte) hash value.
	// It provides a higher level of security compared to SHA-1 and is recommended for newer applications.
	SHA256 = "SHA256"

	// SHA384 represents the SHA-384 hash function.
	// SHA-384 produces a 384-bit (48-byte) hash value.
	// It is a truncated version of SHA-512 and provides a balance between security and performance.
	//
	// Note: Some 2FA mobile apps might not support SHA-384 due to poor ecosystem.
	SHA384 = "SHA384"

	// SHA512 represents the SHA-512 hash function.
	// SHA-512 produces a 512-bit (64-byte) hash value.
	// It offers the highest level of security among the commonly used SHA variants.
	SHA512 = "SHA512"

	// SHA512S224 represents the SHA-512/224 hash function.
	// SHA-512/224 produces a 224-bit (28-byte) hash value.
	// It is a truncated version of SHA-512 and provides a balance between security and performance.
	//
	// Note: Some 2FA mobile apps might not support SHA-512/224 due to poor ecosystem.
	SHA512S224 = "SHA512/224"

	// SHA512S256 represents the SHA-512/256 hash function.
	// SHA-512/256 produces a 256-bit (32-byte) hash value.
	// It is a truncated version of SHA-512 and provides a balance between security and performance.
	//
	// Note: Some 2FA mobile apps might not support SHA-512/256 due to poor ecosystem.
	SHA512S256 = "SHA512/256"

	// BLAKE2b256 represents the secure BLAKE2b hash function with a 256-bit output size.
	// It provides a 256-bit (32-byte) hash value.
	//
	// Note: Some 2FA mobile apps might not support (poor ecosystems) this hash function, so it is recommended to build your own 2FA mobile apps.
	BLAKE2b256 = "BLAKE2b256"

	// BLAKE2b384 represents the secure BLAKE2b hash function with a 384-bit output size.
	// It provides a 384-bit (48-byte) hash value.
	//
	// Note: Some 2FA mobile apps might not support (poor ecosystems) this hash function, so it is recommended to build your own 2FA mobile apps.
	BLAKE2b384 = "BLAKE2b384"

	// BLAKE2b512 represents the secure BLAKE2b hash function with a 512-bit output size.
	// It provides a 512-bit (64-byte) hash value.
	//
	// Note: Some 2FA mobile apps might not support (poor ecosystems) this hash function, so it is recommended to build your own 2FA mobile apps.
	BLAKE2b512 = "BLAKE2b512"

	// BLAKE3256 represents the secure BLAKE3 hash function with a 256-bit output size.
	// It provides a 256-bit (32-byte) hash value.
	// BLAKE3 is a modern, high-performance cryptographic hash function that is faster and more secure than SHA-3 and BLAKE2.
	//
	// Note: Some 2FA mobile apps might not support this hash function due to its relatively new adoption, so it is recommended to build your own 2FA mobile apps when using BLAKE3.
	BLAKE3256 = "BLAKE3256"

	// BLAKE3384 represents the secure BLAKE3 hash function with a 384-bit output size.
	// It provides a 384-bit (48-byte) hash value.
	// BLAKE3 is a modern, high-performance cryptographic hash function that is faster and more secure than SHA-3 and BLAKE2.
	//
	// Note: Some 2FA mobile apps might not support this hash function due to its relatively new adoption, so it is recommended to build your own 2FA mobile apps when using BLAKE3.
	BLAKE3384 = "BLAKE3384"

	// BLAKE3512 represents the secure BLAKE3 hash function with a 512-bit output size.
	// It provides a 512-bit (64-byte) hash value.
	// BLAKE3 is a modern, high-performance cryptographic hash function that is faster and more secure than SHA-3 and BLAKE2.
	//
	// Note: Some 2FA mobile apps might not support this hash function due to its relatively new adoption, so it is recommended to build your own 2FA mobile apps when using BLAKE3.
	BLAKE3512 = "BLAKE3512"
)
View Source
const (
	// NoneStrict represents no strictness for the synchronization window.
	// It has a value of 0, meaning the synchronization window size is not enforced.
	NoneStrict = iota

	// HighStrict represents the highest level of strictness for the synchronization window.
	// It has a value of 1, meaning the synchronization window size is fixed at 1.
	HighStrict

	// MediumStrict represents a medium level of strictness for the synchronization window.
	// It has a value of 2, and the actual synchronization window size is determined by the corresponding range in SyncWindowRanges.
	MediumStrict

	// LowStrict represents a low level of strictness for the synchronization window.
	// It has a value of 3, and the actual synchronization window size is determined by the corresponding range in SyncWindowRanges.
	LowStrict
)
View Source
const (
	// CounterMismatchThreshold1x represents a counter mismatch threshold of 1.
	// If the number of counter mismatches exceeds this threshold,
	// the sync window size will be adjusted to the value defined in the verifier's configuration.
	CounterMismatchThreshold1x = iota + 1

	// CounterMismatchThreshold3x represents a counter mismatch threshold of 3.
	// If the number of counter mismatches exceeds this threshold,
	// the sync window size will be adjusted to the value defined in the verifier's configuration.
	CounterMismatchThreshold3x = iota + 2

	// CounterMismatchThreshold5x represents a counter mismatch threshold of 5.
	// If the number of counter mismatches exceeds this threshold,
	// the sync window size will be adjusted to the value defined in the verifier's configuration.
	CounterMismatchThreshold5x = iota + 3
)
View Source
const (
	// FastCleanup represents the fastest cleanup interval for removing expired tokens in the TOTP verifier.
	// It is assigned a value of iota + 1, which evaluates to 1.
	// When FastCleanup is selected, the cleanup process runs every 25% of the TOTP period, providing the most frequent cleanup.
	FastCleanup = iota + 1

	// MediumCleanup represents a medium cleanup interval for removing expired tokens in the TOTP verifier.
	// It is assigned the next sequential value of iota, which evaluates to 2.
	// When MediumCleanup is selected, the cleanup process runs every 50% of the TOTP period, providing a balanced cleanup frequency.
	MediumCleanup

	// SlowCleanup represents the slowest cleanup interval for removing expired tokens in the TOTP verifier.
	// It is assigned the next sequential value of iota, which evaluates to 3.
	// When SlowCleanup is selected, the cleanup process runs every 75% of the TOTP period, providing the least frequent cleanup.
	SlowCleanup
)

Variables

View Source
var CleanupIntervals = map[int]float64{
	FastCleanup:   0.25,
	MediumCleanup: 0.50,
	SlowCleanup:   0.75,
}

CleanupIntervals is a map that associates cleanup interval constants with their corresponding percentage of the TOTP period. The cleanup interval determines how frequently the cleanup process runs to remove expired tokens.

The available cleanup intervals are:

  • FastCleanup: The cleanup process runs every 25% of the TOTP period.
  • MediumCleanup: The cleanup process runs every 50% of the TOTP period.
  • SlowCleanup: The cleanup process runs every 75% of the TOTP period.

Note: Choosing an appropriate cleanup interval is important to balance the need for timely removal of expired tokens and the overhead of running the cleanup process too frequently. The default cleanup interval is MediumCleanup.

View Source
var DefaultConfig = Config{
	Digits:                  6,
	Period:                  30,
	UseSignature:            false,
	SyncWindow:              HighStrict,
	ResyncWindowDelay:       30 * time.Minute,
	CounterMismatch:         CounterMismatchThreshold3x,
	URITemplate:             "otpauth://%s/%s:%s?secret=%s&issuer=%s&digits=%d&algorithm=%s",
	CustomURITemplateParams: nil,
	Crypto: Crypto{
		Rand:  rand.Read,
		Prime: rand.Prime,
		Int:   rand.Int,
	},
}

DefaultConfig represents the default configuration values.

View Source
var DefaultQRCodeConfig = InitializeDefaultQRCodeConfig()

DefaultQRCodeConfig represents the default configuration for generating QR codes.

View Source
var Hashers = map[string]*gotp.Hasher{
	SHA1:       {HashName: SHA1, Digest: sha1.New},
	SHA224:     {HashName: SHA224, Digest: sha256.New224},
	SHA256:     {HashName: SHA256, Digest: sha256.New},
	SHA384:     {HashName: SHA384, Digest: sha512.New384},
	SHA512:     {HashName: SHA512, Digest: sha512.New},
	SHA512S224: {HashName: SHA512S224, Digest: sha512.New512_224},
	SHA512S256: {HashName: SHA512S256, Digest: sha512.New512_256},
	BLAKE2b256: {HashName: BLAKE2b256, Digest: blake2botp.New256},
	BLAKE2b384: {HashName: BLAKE2b384, Digest: blake2botp.New384},
	BLAKE2b512: {HashName: BLAKE2b512, Digest: blake2botp.New512},
	BLAKE3256:  {HashName: BLAKE3256, Digest: blake3otp.New256},
	BLAKE3384:  {HashName: BLAKE3384, Digest: blake3otp.New384},
	BLAKE3512:  {HashName: BLAKE3512, Digest: blake3otp.New512},
}

Hashers is a map of supported hash functions.

Note: This design allows for flexibility at the top level. For example, it can be used for experimental purposes, such as creating custom hashing functions (advanced use cases) related to cryptography.

View Source
var SyncWindowRanges = map[int][]int{
	MediumStrict: {2, 5},
	LowStrict:    {5, 10},
}

SyncWindowRanges is a map that associates strictness levels with their corresponding ranges of synchronization window sizes. The ranges are used to dynamically calculate the actual synchronization window size based on the counter value:

  • For MediumStrict, the synchronization window size can be between 2 and 5.
  • For LowStrict, the synchronization window size can be between 5 and 10.
  • The HighStrict level does not have a range defined in SyncWindowRanges because it has a fixed synchronization window size of 1.

Also note that there are some considerations to keep in the mind:

  • Security vs. Convenience Trade-off: Increasing the sync window size makes the system more user-friendly since it's less likely to reject valid tokens due to minor synchronization issues. However, a larger window also increases the period during which an attacker can use a stolen OTP to gain unauthorized access.

Functions

This section is empty.

Types

type Config

type Config struct {
	Secret                  string
	Digits                  int
	Period                  int
	UseSignature            bool
	TimeSource              TimeSource
	Counter                 uint64
	CounterMismatch         int
	Hasher                  *gotp.Hasher
	SyncWindow              int
	ResyncWindowDelay       time.Duration
	URITemplate             string
	CustomURITemplateParams map[string]string
	Hash                    string
	Crypto                  Crypto
	CleanupInterval         int
}

Config is a struct that holds the configuration options for the OTP verifier.

func (*Config) DecodeBase32WithPadding added in v0.9.9

func (v *Config) DecodeBase32WithPadding() []byte

DecodeBase32WithPadding decodes a base32-encoded secret, adding padding as necessary.

func (*Config) GenerateSecureRandomCounter added in v0.8.1

func (v *Config) GenerateSecureRandomCounter(maxDigits int) uint64

GenerateSecureRandomCounter generates a random counter number for HOTP with a specified maximum number of digits.

Note: The maximum value for maxDigits is 30. Setting maxDigits to a value greater than 30 may result in integer overflow and panic. Also note that, there is no guarantee about digits for example when set 6 it the result can be possible 5 digits but it secure, the reason why there is no guarantee it requires skilled mathematical reasoning to understand about cryptography

func (*Config) GetHasherByName added in v0.6.2

func (v *Config) GetHasherByName(Hash string) *gotp.Hasher

GetHasherByName returns a pointer to a gotp.Hasher based on the given hash function name. It panics if the hash function name is empty or not supported.

The supported hash function names are:

Note: The hash function name is case-sensitive.

func (*Config) TOTPTime added in v0.9.2

func (v *Config) TOTPTime() time.Time

TOTPTime returns the current time in the South Pole (see https://en.wikipedia.org/wiki/Time_in_Antarctica) time zone. It is used as the default time source for TOTP if no custom time source is provided (nil) and the sync window is set to -1.

Note: The returned time is always expressed in UTC (Coordinated Universal Time) to avoid any ambiguity caused by local time zone offsets.

type Crypto added in v0.9.5

type Crypto struct {
	Rand  func([]byte) (int, error)
	Prime func(rand io.Reader, bits int) (*big.Int, error)
	Int   func(rand io.Reader, max *big.Int) (n *big.Int, err error)
}

Crypto is a struct that holds cryptographic configuration options.

Note: This design allows for flexibility at the top level. For example, it can be used anywhere in this codebase without calling crypto/rand again (DRY). The Rand, Prime, and Int functions are provided as part of the Crypto struct to enable secure random number generation and prime number generation. These functions are used in various cryptographic operations throughout the codebase.

By including them in the Crypto struct, they can be easily accessed and reused without the need to import and call crypto/rand multiple times. This promotes code reusability, maintainability, and adherence to the DRY (Don't Repeat Yourself) principle.

type HOTPVerifier

type HOTPVerifier struct {
	Hotp *gotp.HOTP

	QRCodeBuilder QRCodeConfig
	// contains filtered or unexported fields
}

HOTPVerifier is an HOTP verifier that implements the OTPVerifier interface.

func NewHOTPVerifier

func NewHOTPVerifier(config ...Config) *HOTPVerifier

NewHOTPVerifier creates a new HOTPVerifier with the given configuration.

Note: When using HOTP, consider setting the counter to start from 1. In some 2FA apps, including mobile apps, when a device is registered, the counter is often initialized to 1 when generating the token (e.g., a 6-digit password) because by default, the counter starts at 0 and is hidden the token. Also note that this is still a basic mathematical implementation about counter. More advanced mathematical concepts might be implemented in the future, but not at this time due to the limitations of some mobile 2FA ecosystems (poor ecosystems).

Additionally, using otpverifier.Config.GenerateSecureRandomCounter is recommended instead of starting from 1. Let the client and server roll the counter for the sake of crypto 🎰 by using otpverifier.Config.GenerateSecureRandomCounter.

func (*HOTPVerifier) AdjustSyncWindow added in v0.8.4

func (v *HOTPVerifier) AdjustSyncWindow(threshold int)

AdjustSyncWindow dynamically adjusts the size of the synchronization window based on the frequency of counter mismatches between the server and the client.

Note: This is a long-term adjustment bound to real-time on Earth. For example, in the year 2024 (now), if the server's counter is far behind (e.g., the client has already reached a counter value of 1 billion), it may take until the year 3024 for the server and client to be fully synchronized again. The adjustment process is gradual and occurs over an extended period. This approach ensures a smooth and secure synchronization process, preventing sudden and drastic changes to the sync window size. It allows the system to adapt to counter mismatches while maintaining the integrity and security of the HOTP verification process.

func (*HOTPVerifier) BuildQRCode added in v0.5.6

func (v *HOTPVerifier) BuildQRCode(issuer, accountName string) ([]byte, error)

BuildQRCode generates a QR code image for the OTP configuration.

func (*HOTPVerifier) GenerateOTPURL added in v0.6.4

func (v *HOTPVerifier) GenerateOTPURL(issuer, accountName string) string

GenerateOTPURL creates the URL for the QR code based on the provided URI template.

func (*HOTPVerifier) GenerateToken

func (v *HOTPVerifier) GenerateToken() string

GenerateToken generates a token for the current counter value.

func (*HOTPVerifier) GenerateTokenWithSignature added in v0.7.9

func (v *HOTPVerifier) GenerateTokenWithSignature() (string, string)

GenerateTokenWithSignature generates a token and signature for the current counter value.

func (*HOTPVerifier) GetCounter added in v0.5.8

func (v *HOTPVerifier) GetCounter() uint64

GetCounter returns the current counter value from the HOTPVerifier's configuration.

func (*HOTPVerifier) GetSyncWindow added in v0.6.1

func (v *HOTPVerifier) GetSyncWindow() int

GetSyncWindow returns the current synchronization window value from the HOTPVerifier's configuration.

func (*HOTPVerifier) ResetSyncWindow added in v0.6.1

func (v *HOTPVerifier) ResetSyncWindow(newSyncWindow ...int)

ResetSyncWindow resets the synchronization window to a default or specified value. If no value is provided, it resets to the default value defined in DefaultConfig.

func (*HOTPVerifier) SaveQRCodeImage added in v0.5.6

func (v *HOTPVerifier) SaveQRCodeImage(issuer, accountName, filename string) error

SaveQRCodeImage saves the QR code image to a file.

func (*HOTPVerifier) SetCounter added in v0.5.8

func (v *HOTPVerifier) SetCounter(counter uint64)

SetCounter sets the counter value in the HOTPVerifier's configuration.

func (*HOTPVerifier) Verify

func (v *HOTPVerifier) Verify(token string, signature ...string) bool

Verify checks if the provided token and signature are valid for the specified counter value. If the 'SyncWindow' configuration is greater than 1, the method will validate the token against a range of counter values defined by the current counter and the sync window size. This allows for a degree of error tolerance in scenarios where the verifier's counter may be out of sync with the token generator's counter. If the 'UseSignature' configuration is set to true, the method also verifies the provided signature against the expected signature for the token. A successful verification will result in the counter being updated to the next expected value.

Note: A firm grasp of the sync window concept is essential for understanding its role in the verification process.

type OCRAVerifier added in v0.9.8

type OCRAVerifier struct {
	// contains filtered or unexported fields
}

OCRAVerifier is an OCRA verifier (RFC 6287) that implements the OTPVerifier interface.

Definition of OCRA:

OCRA(K, C, Q, P, S) = HOTP(K, C || Q || P || S)

Where:

  • K is the shared secret key between the client and the server.
  • C is the counter value, which is a 64-bit unsigned integer.
  • Q is the challenge question, which is a string containing the question or prompt.
  • P is the hash algorithm used in the HMAC calculation (e.g., SHA-1, SHA-256).
  • S is the session information, which can include additional parameters such as the session identifier, timestamp, or nonce.
  • || denotes concatenation of the input values.

The HOTP function used in the OCRA algorithm is defined as follows:

HOTP(K, C) = Truncate(HMAC-SHA-1(K, C))

Where:

  • Truncate is a function that selects a subset of bits from the HMAC result to generate the final HOTP value.
  • HMAC-SHA-1 is the HMAC function using the SHA-1 hash algorithm. Other hash algorithms like SHA-256 or SHA-512 can also be used.

The Truncate function is defined as follows:

Truncate(HMAC(K, C)) = HOTP

Where:

  • HMAC(K, C) is the HMAC result using the shared secret key K and the concatenated input C.
  • HOTP is the resulting HOTP value, which is typically a 6-digit or 8-digit decimal number.

Note: These docs provide a simplified explanation of the cryptographic concepts to improve readability and understanding.

func NewOCRAVerifier added in v0.9.8

func NewOCRAVerifier(config ...Config) *OCRAVerifier

NewOCRAVerifier creates a new OCRAVerifier with the given configuration.

Note: This requires building own 2FA apps because it involves a question-answer process. For example, a mobile app can be built to generate OCRA tokens based on the shared secret key and the challenge. The app would prompt the user with the question from the challenge and expect the user to provide the correct answer. The answer, along with other parameters like the counter value, would be used to generate the OCRA token. The generated token can then be entered by the user on the server-side for verification. Building own 2FA app allows customizing the user experience and integrating OCRA seamlessly into the authentication flow.

func (*OCRAVerifier) GenerateOTPURL added in v0.9.8

func (v *OCRAVerifier) GenerateOTPURL(issuer, accountName string) string

GenerateOTPURL creates the URL for the QR code based on the provided URI template.

TODO: Build a custom URI for the OCRA token. Currently, this function is unused because most mobile apps have poor ecosystems and may not be capable of handling cryptographic operations hahaha.

func (*OCRAVerifier) GenerateToken added in v0.9.8

func (v *OCRAVerifier) GenerateToken(challenge string) string

GenerateToken generates an OCRA token based on the provided challenge.

func (*OCRAVerifier) GenerateTokenWithSignature deprecated added in v0.9.8

func (v *OCRAVerifier) GenerateTokenWithSignature() (string, string)

GenerateTokenWithSignature is not applicable for OCRA, so it panics.

Deprecated: No-op for OCRA (deadcode)

func (*OCRAVerifier) GetCounter deprecated added in v0.9.8

func (v *OCRAVerifier) GetCounter() uint64

GetCounter is not applicable for OCRA, so it returns 0.

Deprecated: No-op for OCRA (deadcode)

func (*OCRAVerifier) SetCounter deprecated added in v0.9.8

func (v *OCRAVerifier) SetCounter(counter uint64)

SetCounter is not applicable for OCRA, so it does nothing.

Deprecated: No-op for OCRA (deadcode)

func (*OCRAVerifier) Verify added in v0.9.8

func (v *OCRAVerifier) Verify(token string, challenge string) bool

Verify checks if the provided token and signature are valid for the specified challenge.

type OTPVerifier

type OTPVerifier interface {
	Verify(token string, signature ...string) bool
	GenerateToken() string
	GenerateTokenWithSignature() (string, string)
	SetCounter(counter uint64)
	GetCounter() uint64
	GenerateOTPURL(issuer, accountName string) string
}

OTPVerifier is an interface that defines the behavior of an OTP verifier.

func OTPFactory

func OTPFactory(config Config) OTPVerifier

OTPFactory is a simple factory function to create an OTPVerifier. It takes a Config and creates the appropriate verifier based on the configuration.

type QRCodeConfig added in v0.5.4

type QRCodeConfig struct {
	Level              qrcode.RecoveryLevel
	Size               int
	ForegroundColor    color.Color
	BackgroundColor    color.Color
	DisableBorder      bool
	TopText            string
	BottomText         string
	Font               font.Face
	TopTextPosition    image.Point
	BottomTextPosition image.Point
	FilePath           string
}

QRCodeConfig represents the configuration for generating QR codes.

func InitializeDefaultQRCodeConfig added in v0.5.4

func InitializeDefaultQRCodeConfig() QRCodeConfig

InitializeDefaultQRCodeConfig sets up the default configuration for generating QR codes with dynamic text positions.

func (*QRCodeConfig) GenerateQRCodeImage added in v0.6.4

func (qr *QRCodeConfig) GenerateQRCodeImage(otpURL string) (image.Image, error)

GenerateQRCodeImage generates a QR code image based on the provided OTP URL and configuration.

TODO: Implement the following features:

  • Allow placing a logo in the middle of the QR code
  • Customize the theme (e.g., changing color, layout) beyond the default QR code system

Note: These features require additional implementation and may involve modifying the QRCodeConfig struct and the GenerateQRCodeImage function.

type TOTPVerifier

type TOTPVerifier struct {
	UsedTokens      *sync.Map
	CleanupInterval int
	QRCodeBuilder   QRCodeConfig
	// contains filtered or unexported fields
}

TOTPVerifier is a TOTP verifier that implements the OTPVerifier interface.

func NewTOTPVerifier

func NewTOTPVerifier(config ...Config) *TOTPVerifier

NewTOTPVerifier creates a new TOTPVerifier with the given configuration.

func (*TOTPVerifier) BuildQRCode added in v0.5.4

func (v *TOTPVerifier) BuildQRCode(issuer, accountName string) ([]byte, error)

BuildQRCode generates a QR code image for the OTP configuration.

func (*TOTPVerifier) CleanUpExpiredTokens added in v0.6.5

func (v *TOTPVerifier) CleanUpExpiredTokens()

CleanUpExpiredTokens removes expired tokens from the usedTokens map.

func (*TOTPVerifier) GenerateOTPURL added in v0.6.4

func (v *TOTPVerifier) GenerateOTPURL(issuer, accountName string) string

GenerateOTPURL creates the URL for the QR code based on the provided URI template.

func (*TOTPVerifier) GenerateToken

func (v *TOTPVerifier) GenerateToken() string

GenerateToken generates a token for the current time.

func (*TOTPVerifier) GenerateTokenWithSignature added in v0.7.9

func (v *TOTPVerifier) GenerateTokenWithSignature() (string, string)

GenerateTokenWithSignature generates a token and signature for the current time.

func (*TOTPVerifier) GetCounter deprecated added in v0.5.8

func (v *TOTPVerifier) GetCounter() uint64

GetCounter always returns 0 for TOTPVerifier since TOTP doesn't use a counter.

Deprecated: No-op for TOTP (deadcode)

func (*TOTPVerifier) SaveQRCodeImage added in v0.5.4

func (v *TOTPVerifier) SaveQRCodeImage(issuer, accountName, filename string) error

SaveQRCodeImage saves the QR code image to a file.

func (*TOTPVerifier) SetCounter deprecated added in v0.5.8

func (v *TOTPVerifier) SetCounter(counter uint64)

SetCounter is a no-op for TOTPVerifier since TOTP doesn't use a counter.

Deprecated: No-op for TOTP (deadcode)

func (*TOTPVerifier) Verify

func (v *TOTPVerifier) Verify(token string, signature ...string) bool

Verify checks if the provided token and signature are valid for the current time.

Note: This TOTP verification using crypto/subtle requires careful consideration when setting TimeSource and Period to ensure correct usage.

type TimeSource

type TimeSource func() time.Time

TimeSource is a function type that returns the current time.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL