/// <summary> /// Remaining seconds in current window based on UtcNow /// </summary> /// <remarks> /// It will be corrected against a corrected UTC time using the provided time correction. If none was provided then simply the current UTC will be used. /// </remarks> /// <returns>Number of remaining seconds</returns> //public int RemainingSeconds() //{ // return RemainingSecondsForSpecificTime(this.correctedTime.CorrectedUtcNow); //} /// <summary> /// Remaining seconds in current window /// </summary> /// <param name="timestamp">The timestamp</param> /// <returns>Number of remaining seconds</returns> //public int RemainingSeconds(DateTime timestamp) //{ // return RemainingSecondsForSpecificTime(this.correctedTime.GetCorrectedTime(timestamp)); //} //private int RemainingSecondsForSpecificTime(DateTime timestamp) //{ // return this.step - (int)(((timestamp.Ticks - unixEpochTicks) / ticksToSeconds) % this.step); //} /// <summary> /// Takes a time step and computes a TOTP code /// </summary> /// <param name="counter">time step</param> /// <param name="mode">The hash mode to use</param> /// <returns>TOTP calculated code</returns> protected override string Compute(long counter, OtpHashMode mode) { var data = KeyUtilities.GetBigEndianBytes(counter); var otp = this.CalculateOtp(data, mode); return(Digits(otp, this.totpSize)); }
//readonly MemoryProtectionScope scope; #region static initializers /// <summary> /// Static method to create a protected key from a plaintext key. It will wipe the reference that was passed in once the protected key instance is initialized /// </summary> /// <param name="plaintextKey">The key</param> /// <returns>A protected key instance from the provided key</returns> public static InMemoryKey CreateProtectedKeyAndDestroyPlaintextKey(byte[] plaintextKey) { var key = new InMemoryKey(plaintextKey); // the protected key creates a copy of the key and pads it as needed for in memory protection. // Thus the reference that was passed in isn't needed. Overwrite it with random garbage. KeyUtilities.Destroy(plaintextKey); return(key); }
/// <summary> /// Uses the key to get an HMAC using the specified algorithm and data /// </summary> /// <param name="mode">The HMAC algorithm to use</param> /// <param name="data">The data used to compute the HMAC</param> /// <returns>HMAC of the key and data</returns> public byte[] ComputeHmac(OtpHashMode mode, byte[] data) { byte[] hashedValue = null; using (HMAC hmac = CreateHmacHash(mode)) { byte[] key = this.GetCopyOfKey(); try { hmac.Key = key; hashedValue = hmac.ComputeHash(data); } finally { KeyUtilities.Destroy(key); } } return(hashedValue); }