Otp.NET Documentation

repository·master·Indexed 23 days ago

https://github.com/kspearrin/otp.net

A C# implementation of TOTP (RFC 6238) and HOTP (RFC 4226) algorithms for two-factor authentication. It provides classes for calculating and verifying codes, handling time drift via TimeCorrection, generating OTP URIs for apps like Google Authenticator, and Base32 encoding for secret keys.

Tokens
942
Snippets
2
Records
8
Agent score
30%

What's inside Otp.NET

  1. How HOTP (HMAC-based One Time Password) works

    master

    HOTP is a counter-based algorithm (RFC 4226). You create an Hotp instance with a shared secret key.

    Configuration options:

    • mode: The hash algorithm (defaults to OtpHashMode.Sha1, supports Sha256 and Sha512).
    • hotpSize: The number of digits in the code (defaults to 6).

    To verify an HOTP code, use VerifyHotp, which requires the current counter value.

  2. How TOTP (Timed One Time Password) works

    master

    TOTP uses a rolling window of time to calculate single-use passwords, commonly used for two-factor authentication (e.g., Google Authenticator). In Otp.NET, you create a Totp instance by providing a shared secret key as a byte array.

    Key configuration options during construction include:

    • mode: The hash algorithm (defaults to OtpHashMode.Sha1, but supports Sha256 and Sha512).
    • step: The time step window in seconds (RFC recommends 30 seconds).
    • totpSize: The number of digits in the code (defaults to 6, but can be set to 8).
    • timeCorrection: An optional TimeCorrection object to handle clock drift between client and server.
  3. Calculate and verify TOTP codes

    master

    Use the ComputeTotp method to generate a code. You can provide a specific DateTime (recommended DateTime.UtcNow) or use the parameterless overload which defaults to UtcNow.

    To verify a code, use VerifyTotp. This method returns a bool and provides an out long timeWindowUsed parameter. The timeWindowUsed represents the specific time window where the match occurred; you should persist this value to ensure a code is only used once per window, as per RFC 6238.

  4. Configure verification windows for TOTP

    master

    By default, VerifyTotp only accepts the code for the current time step. To account for network delay or slight clock desynchronization, you can provide a VerificationWindow object.

    • VerificationWindow.RfcSpecifiedNetworkDelay: A constant that implements the RFC recommendation (allowing the current step, one step prior, and one step ahead).
    • Custom windows: You can manually specify previous and future steps.

    Example of a custom window allowing 1 step prior and 1 step ahead: var window = new VerificationWindow(previous: 1, future: 1);

  5. Use Base32 encoding for OTP keys

    master

    OTP secrets are often handled as Base32 strings. The Base32Encoding helper class provides methods to convert between byte arrays and Base32 strings.

    var key = KeyGeneration.GenerateRandomKey(20);
    
    // Convert bytes to Base32 string
    var base32String = Base32Encoding.ToString(key);
    
    // Convert Base32 string back to bytes
    var base32Bytes = Base32Encoding.ToBytes(base32String);
    
    var otp = new Totp(base32Bytes);
  6. Generate OTP URIs

    master

    The OtpUri class allows you to generate URIs in the 'Key Uri Format' used by apps like Google Authenticator.

    Constructor parameters:

    • otpType: The type of OTP (OtpType.Totp or OtpType.Hotp).
    • secret: The shared secret (as a Base32 string).
    • accountName: The user's account identifier (e.g., email).
    • issuer: The name of the service/issuer.
  7. Handle time drift with TimeCorrection

    master

    If the server's system time is significantly different from the authoritative time (e.g., NIST), use the TimeCorrection class. This creates an offset that is applied to all subsequent time calculations and verifications performed by the Totp instance.

    1. Create a TimeCorrection object using the current correct UTC time.
    2. Pass this object into the Totp constructor via the timeCorrection parameter.