[SOLVED] Can’t decrypt password string anymore when closing and starting application again

Issue

This Content is from Stack Overflow. Question asked by SimonS

I’m learning C# and am trying to implement a Login Function. I have a registration form, a login form and my data (including this user information) gets saved into an XML File.

I have the following Class:

public static class UserController
{
    // Inspiration from https://stackoverflow.com/questions/12657792/how-to-securely-save-username-password-local
    private static readonly byte[] entropy = new byte[20];

    public static string EncryptString(string password)
    {
        // Convert Password to byte[]
        byte[] data = Encoding.UTF8.GetBytes(password);

        // use RandomNumberGenerator instead of using RNGCryptoServiceProvider which is obsolete 
        //https://stackoverflow.com/questions/72418725/rngcryptoserviceprovider-is-obsolete
        using (var rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(entropy);
        }

        // Protect (Encrypt) the String
        byte[] ciphertext = ProtectedData.Protect(data, entropy, DataProtectionScope.CurrentUser);

        // return as Base64
        return Convert.ToBase64String(ciphertext);
    }

    public static string DecryptString(string password)
    {
        byte[] plaintext = ProtectedData.Unprotect(Convert.FromBase64String(password), entropy, DataProtectionScope.CurrentUser);
        return Encoding.UTF8.GetString(plaintext);
    }


    public static bool CheckLoginCredentials(string username, string password)
    {
        bool isOK = false;
        var myUser = XmlHandler.GetUserFromXml(username);
        if (myUser != null)
        {
            // Decrypt Password
            string plainpassword = DecryptString(myUser.Password);
            if (username == myUser.UserName && password == plainpassword)
                isOK = true;
        }
        return isOK;
    }
}

When I create a User in my registration form (which gets his password encrypted with DecryptString()) and then Login with that user, everything works.
However, if I close the application and try to login again, the DecryptString() can’t decrypt the Password to plain text anymore.

Why is that? Do I have to store a key somewhere?

Solution

The point of generating entropy is that it’s random – It’s highly unlikely to contain the same values twice in a row, therefore you can’t use to decrypt a password after restarting your application.

However, you should never need to decrypt a password – you should just verify it’s correct via a hash. See BCrypt.NET as an example.

Answered by jeanluc162

This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 2.5.CC BY-SA 3.0.CC BY-SA 4.0.

people found this article helpful. What about you?