OtpCore 1.1.4

There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package OtpCore --version 1.1.4                
NuGet\Install-Package OtpCore -Version 1.1.4                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OtpCore" Version="1.1.4" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add OtpCore --version 1.1.4                
#r "nuget: OtpCore, 1.1.4"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install OtpCore as a Cake Addin
#addin nuget:?package=OtpCore&version=1.1.4

// Install OtpCore as a Cake Tool
#tool nuget:?package=OtpCore&version=1.1.4                

Build status nuget License

OtpCore

HOTP, TOTP, OTP Auth URI, and Base32 implementation in C# targeting .NET standard 2.0, compliant with:

It has been verified against test vectors supplied in the RFCs. The interface includes support for multiple algorithms:

  • HMAC-SHA1
  • HMAC-SHA256
  • HMAC-SHA384
  • HMAC-SHA512

It supports variable code lengths (6 - 10) and an adjustable period, or time step, (1 second - 1 hour) for TOTP.

The reason for creating this library was to fetch multiple HOTP counters or a TOTP time range in a single call.

A parser for OTP Auth URIs (otpauth://) is also included that conforms to the documentation found at: https://github.com/google/google-authenticator/wiki/Key-Uri-Format.

This implementation also includes a Base32 encoder and decoder. It is compliant with RFC 4648, using the standard alphabet from section 6, and has been tested against the test vectors from section 10.

It's free. Enjoy!

Examples

Authenticators

OtpCore provides HotpAuthenticator and TotpAuthenticator classes which can be instantiated from a OTP Auth URI using the GetAuthenticator() method in the Hotp and Totp classes.

HOTP

// Create from string
var uriString = "otpauth://hotp/NOBODY:petrsnd@gmail.com?issuer=NOBODY&secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ&algorithm=SHA1&digits=6&counter=0";
var authenticator = Hotp.GetAuthenticator(uriString);

// Create from Uri object
var uri = new Uri(uriString);
authenticator = Hotp.GetAuthenticator(uri);

// Create from scratch by supplying parameters
var secret = Encoding.ASCII.GetBytes("12345678901234567890");
var account = "bob@example.corp";
var issuer = "Example";
var counter = 0;
var otpAuthUri = new OtpAuthUri(OtpType.Hotp, secret, account, issuer, counter); // issuer is optional, digits defaults to 6
authenticator = Hotp.GetAuthenticator(otpAuthUri);

// Get a code or a sequence of codes
var code = authenticator.GetCode();
var sequence = authenticator.GetSequence(3);

// Increment or set the counter
authenticator.IncrementCounter();
authenticator.SetCounter(3);

// Revert back to a string for storage with updated counter in URI
// The URI is left unchanged unless IncrementCounter() or SetCounter() are called
uriString = authenticator.ToString();

TOTP

// Create from string
var uriString = "otpauth://totp/NOBODY:petrsnd@gmail.com?issuer=NOBODY&secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZA&algorithm=SHA256&digits=8";
var authenticator = Totp.GetAuthenticator(uriString);

// Create from Uri object
var uri = new Uri(uriString);
authenticator = Totp.GetAuthenticator(uri);

// Create from scratch by supplying parameters
var secret = Encoding.ASCII.GetBytes("12345678901234567890");
var account = "bob@example.corp";
var issuer = "Example";
// issuer is optional, digits defaults to 6, period defaults to 30
var otpAuthUri = new OtpAuthUri(OtpType.Totp, secret, account, issuer);
authenticator = Totp.GetAuthenticator(otpAuthUri);

// Get a code or a range of codes
var code = authenticator.GetCode();
var range = authenticator.GetRange(TimeSpan.FromSeconds(90));
// No counter to manage with TOTP.  Yay!!!

// Revert back to a string for storage if it was created from scratch
uriString = authenticator.ToString();

Static Methods

OtpCore may also be used as a static utility library by only calling the static methods for HOTP and TOTP. When used this way, no object tracks counters or store secrets.

Fetch a simple code.

// Hotp
var secret = Encoding.ASCII.GetBytes("12345678901234567890");
long counter = 0;
int digits = 6;
var hotpCode = Hotp.GetHotpCode(secret, counter, OtpHmacAlgorithm.HmacSha1, digits));

// Totp
int period = 30;
digits = 8;
long unixTime = 1111111111; // 2005-03-18 01:58:31 +0:00
var totpCode = Totp.GetTotpCode(secret, unixTime, period, OtpHmacAlgorithm.HmacSha1, digits);

var timeFuture = DateTimeOffset.Parse("2033-05-18 03:33:20 -7:00"); // future DateTimeOffset
totpCode = Totp.GetTotpCode(secret, timeFuture, period, OtpHmacAlgorithm.HmacSha1, digits);

totpCode = Totp.GetTotpCode(secret, DateTimeOffset.Now, period, OtpHmacAlgorithm.HmacSha1, digits); // Now

Fetch multiple codes.

// Hotp
var secret = Encoding.ASCII.GetBytes("12345678901234567890");
long counter = 0;
int sequenceLength = 5; // next 5 codes
int digits = 6;
var hotpValues = Hotp.GetHotpCode(secret, counter, sequenceLength, OtpHmacAlgorithm.HmacSha1, digits));

// Totp
int period = 30;
digits = 8;
var range = TimeSpan.FromSeconds(120); // two minutes worth of codes
var totpValues = Totp.GetTotpRange(secret, DateTimeOffset.Now, range, period, OtpHmacAlgorithm.HmacSha1, digits);

Base32 Encoding and Decoding

You may just want a simple Base32 encoder/decoder, because it isn't supplied in the .NET SDK.

var buffer = Encoding.ASCII.GetBytes("12345678901234567890");
var encoded = Utilities.Base32Encode(buffer); // GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ
var decoded = Utilities.Base32Decode(encoded);
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.2.0-dev-78 82 10/3/2024
1.2.0-dev-72 79 10/3/2024
1.2.0-dev-70 78 10/3/2024
1.2.0-dev-67 186 7/5/2023
1.2.0-dev-66 198 1/24/2023
1.2.0-dev-65 195 1/24/2023
1.2.0-dev-64 181 1/24/2023
1.2.0-dev-58 186 1/24/2023
1.1.4 232 10/3/2024
1.1.2 2,689 1/24/2023
1.1.1 370 1/23/2023
1.1.0 397 1/17/2023
1.1.0-dev-54 181 1/23/2023
1.1.0-dev-52 179 1/23/2023
1.1.0-dev-48 204 1/17/2023
1.1.0-dev-46 178 1/17/2023
1.1.0-dev-44 187 1/17/2023
1.1.0-dev-40 198 1/16/2023
1.1.0-dev-32 215 8/18/2022
1.1.0-dev-28 197 8/18/2022
1.1.0-dev-24 189 8/17/2022
1.1.0-dev-22 207 7/30/2022
1.0.3 528 8/18/2022
1.0.2 482 8/17/2022
1.0.1 508 7/30/2022
1.0.1-dev-17 224 7/30/2022
1.0.0 515 7/29/2022
0.9.0-dev-9 203 7/29/2022
0.9.0-dev-8 199 7/29/2022
0.9.0-dev-7 189 7/29/2022
0.9.0-dev-6 208 7/28/2022
0.9.0-dev-14 220 7/29/2022
0.9.0-dev-13 210 7/29/2022
0.9.0-dev-12 207 7/29/2022
0.9.0-dev-11 205 7/29/2022
0.9.0-dev-10 211 7/29/2022

- Tested against more 2FA provider URIs to ensure compatibility
- Added a test tool for generating QR codes
- Fixed some library and parsing bugs
- Fixed Issuer encoding and period allowable range