Skip to content

Add IsPasswordValid method #7

Description

@NimeshDhruve

It would be great if you can also provide method to validate password for both HOTP and TOTP.

I took a crack at it by implementing this inside Totp.cs but wasn't able to get it working as expected

        public bool IsPasswordValid(string password)
        {
            long givenUnixTime = UnixTime.GetUnixTime();
            return IsValidPassword(password, givenUnixTime);
        }

        public bool IsValidPassword(string password, DateTime dateTime)
        {
            long givenUnixTime = UnixTime.GetUnixTime(dateTime);
            return IsValidPassword(password, givenUnixTime);
        }

        public override bool IsValidPassword(string password, long timeCounter)
        {
            var currentPassword = GeneratePassword(timeCounter);            
            return currentPassword == password;
        }

Code for testing this change:

       Random _random = new Random();
        char GetRandomLetter()
        {
            // This method returns a random lowercase letter.
            // ... Between 'a' and 'z' inclusize.
            int num = _random.Next(0, 26); // Zero to 25
            char let = (char)('a' + num);
            return let;
        }

        string GetRandomSecretKey()
        {
            var firstSet = new string(new char[] { GetRandomLetter(), GetRandomLetter(), GetRandomLetter(), GetRandomLetter() });
            var secondSet = new string(new char[] { GetRandomLetter(), GetRandomLetter(), GetRandomLetter(), GetRandomLetter() });
            var thridSet = new string(new char[] { GetRandomLetter(), GetRandomLetter(), GetRandomLetter(), GetRandomLetter() });
            var fourthSet = new string(new char[] { GetRandomLetter(), GetRandomLetter(), GetRandomLetter(), GetRandomLetter() });
            return string.Join(" ", firstSet, secondSet, thridSet, fourthSet);
        }

        private async void TestMeghod()
        {
            int passwordSize = 6;

            for (int timeStep = 30; timeStep < 200; timeStep++) /*Loop for various time steps starting with 30 seconds*/
            {
                var secretKey = GetRandomSecretKey(); /*Create separate random key for each time step*/
                byte[] secret = System.Text.Encoding.ASCII.GetBytes(secretKey); 
                var otpGenerator = new Totp(secret, passwordSize) { TimeInterval = timeStep };
                var sp = Stopwatch.StartNew();
                Debug.WriteLine($"TimeStep: {timeStep}, Key: {secretKey}, Started: {DateTime.Now.ToString("hh:mm:ss.fff")}");
                //Generate password
                var code = otpGenerator.GeneratePassword();
                //And now verify this password for timeStep + some buffer to ensure it is working correctly.
                for (int i = 0; i < timeStep + 60; i++)
                {
                    await Task.Delay(1000); /*Wait for 1 second and then try to validate the password*/
                    var otpVerfier = new Totp(secret, passwordSize) { TimeInterval = timeStep }; /*Create a new instance as in production environment Server and client both will have different instances.*/
                    var isCodeValid = otpVerfier.IsPasswordValid(code); /*Now verify it for given time.*/
                    var wrongResult = (sp.Elapsed.TotalSeconds > timeStep) && isCodeValid;
                    //Print some details of this attempt
                    Debug.WriteLine($"ValidCode: {isCodeValid}, {sp.Elapsed}{(wrongResult ? $", Not good {timeStep}" : "")}{(isCodeValid ? "":$", {timeStep}")}");
                    if (isCodeValid == false) /*As soon as code is invalid move on, no need to sleep further*/
                        break;
                }
                Debug.WriteLine($"TimeStep: {timeStep}, Key: {secretKey}, Ended: {DateTime.Now.ToString("hh:mm:ss.fff")}");
            }

        }

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions