public ITOTPResult GetCodes(string hashAlgorithm, byte[] key, TOTPOptions options = null) { if (!this.hashAlgorithms.TryGetValue(hashAlgorithm, out var hashAlgorithmProvider)) { throw new AlgorithmNotFoundException(hashAlgorithm); } if (key is null) { throw new ArgumentNullException(nameof(key)); } if (options is null) { options = TOTPOptions.Default; } using var hmac = hashAlgorithmProvider.GetHash(key); var secondsSinceEpoch = (ulong)(this.systemClock.UtcNow - unixEpoch).TotalSeconds; var validFor = 30 - (secondsSinceEpoch % (uint)options.Period); var timePeriod = secondsSinceEpoch / (uint)options.Period; var currentCode = this.GetOneCode(hmac, timePeriod, options.Digits); var previousCodes = Enumerable.Range(0, options.PriorPeriods) .Select(x => this.GetOneCode(hmac, timePeriod - (ulong)x - 1, options.Digits)); var followingCodes = Enumerable.Range(0, options.FollowingPeriods) .Select(x => this.GetOneCode(hmac, timePeriod + (ulong)x + 1, options.Digits)); return(new TOTPResult(currentCode, TimeSpan.FromSeconds(validFor), previousCodes, followingCodes)); }
public void TestsFromRFC6238(string dateTime, string key, string code, string algorithm) { var totpOptions = new TOTPOptions(digits: 8); var totpProvider = new ServiceCollection() .AddTOTP() .AddSingleton <ISystemClock>(new ExplicitSystemClock(dateTime)) .BuildServiceProvider() .GetRequiredService <ITOTPProvider>(); var result = totpProvider.GetCodes(algorithm, key, totpOptions); Assert.Equal(code, result.CurrentCode); }
public ITOTPResult GetCodes(string hashAlgorithm, string key, TOTPOptions options = null) => this.GetCodes(hashAlgorithm, Base32.Decode(key), options);