Why is Dictionary<TKey,TValue>.TryGetValue(TKey, TValue) always returning true?

42 views Asked by At

I'm trying to use Dictionary.TryGetValue() to search a dictionary for a username and password hash, if it matches authenticate the user, if not do something else.

The problem I'm having is that anytime the hash value does not match what's in the dictionary it returns true anyways, maybe because it matched the username key? Is it expected behavior to return true if only the key but not that value matches?

I've included my method and user output below. I'm printing the hashes for troubleshooting purposes.

Here's example user output where the hash matches and then it doesn't:

It does not change behavior if the hash doesn't match the first time

PASSWORD AUTHENTICATION SYSTEM

Please select one option:

  1. Establish an account
  2. Authenticate a user
  3. Exit the system

Enter selection: 1 Enter your username: username

Enter password: username, 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8]

PASSWORD AUTHENTICATION SYSTEM

Please select one option:

  1. Establish an account
  2. Authenticate a user
  3. Exit the system

Enter selection: 2 Enter username you would like to authenticate Username: username

Enter password: 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 Successfully authenticated as username

PASSWORD AUTHENTICATION SYSTEM

Please select one option:

  1. Establish an account
  2. Authenticate a user
  3. Exit the system

Enter selection: 2 Enter username you would like to authenticate Username: username

Enter password: 152f66d0fe3a409590ec40fea1ee037cefb4549a1f511defd16824117a768b1d 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8

Successfully authenticated as username

Below is the authentication method

        static void authUser(string userName)
        {
            if (!passDB.ContainsKey(userName))
                Console.WriteLine($"Username \"{userName}\" does not exist.");
            else if (passDB.ContainsKey(userName))
            {
                string secret;
                string testHash;
                int tryCount = 4;

                do
                {
                    secret = HidePassInput();

                    SHA256 sha256Hash = SHA256.Create();
                    testHash = GetHash(sha256Hash, secret);
                    Console.WriteLine(testHash);
                    if (passDB.TryGetValue(userName, out testHash))
                    {
                        Console.WriteLine(testHash);
                        Console.WriteLine($"Successfully authenticated as {userName}\n");
                        tryCount = 0;
                    }
                    else
                    {
                        tryCount--;
                        Console.WriteLine($"Failed to autheticate as {userName}. {tryCount} more tries left.\n");
                    }
                    
                } while (tryCount > 0);
            }
        }
1

There are 1 answers

1
DarkSigma On

It appears that you are misunderstanding the use of the TryGetValue method.

The first parameter is the key for which you want to get its value. The second parameter is an out parameter. If the key exists, its value will be assigned to the variable that you've used as argument to the out parameter. Whatever value was held by testHash is overwritten.

TryGetValue does not receive a value that you are looking for. It only receives a key. It returns true if that key is found, otherwise false. The value of the found key is assigned to the out variable.