Working with Registry in C# 2.0 (Windows Forms)

2020-02-12 19:00发布

问题:

I'm a newbie to Windows Forms.

I'm designing an Windows Application in .Net Framework 2.0 in which, I need to Store a UserName and Password somewhere in the System and access them every time I open My Application and Some times I need to change those credentials on User command.

I heard registry is the Best way in doing so. I know Nothing About Using Registry in C# .Net.

So Can you Help me in

How To Get Values which are In Registry, and how to Set a Value to Registry. ??

I'm Using .Net Framework 2.0

回答1:

The subject is very broad. You should start reading on MSDN about the class

Microsoft.Win32.RegistryKey

But I really suggest to avoid the registry altogether.
Allowing the registry to store configuration info for normal applications has been a mistake from the start by Microsoft.

You could write a simple hashing function, apply it to your username and password and store the result in a file located in the ApplicationData folder. At the next run check if the file exist, read it and compare its content with the hashing of username and password.

Here a rough example, just to let you start on your own code.

private void button1_Click(object sender, EventArgs e)
{
    string user = "Steve";
    string pass = "MyPass";

    string hashedUser = GetHashedText(user);
    string hashedPass = GetHashedText(pass);

    string file = Path.Combine(Environment.GetFolderPath 
                       (Environment.SpecialFolder.ApplicationData), 
                       "MyKeys.txt");

    if (File.Exists(file))
    {
        using (StreamReader sr = new StreamReader(file))
        {
            string recordedUser = sr.ReadLine();
            string recordedPass = sr.ReadLine();
            if (recordedUser == user && recordedPass == pass)
                MessageBox.Show("User validated");
            else
                MessageBox.Show("Invalid user");
        }
    }
    else
    {
        using (StreamWriter sw = new StreamWriter(file, false))
        {
            sw.WriteLine(hashedUser);
            sw.WriteLine(hashedPass);
        }

    }
}

private string GetHashedText(string inputData)
{ 
    byte[] tmpSource;
    byte[] tmpData;
    tmpSource = ASCIIEncoding.ASCII.GetBytes(inputData);
    tmpData = new MD5CryptoServiceProvider().ComputeHash(tmpSource);
    return Convert.ToBase64String(tmpData);
}

EDIT: Based on your comment, it seems that you need a crypt and decrypt function. The code below is taken and adapted from the Extension Overflow, where you can find other useful methods. Now, before write to disk, call the Encrypt method with the string to encrypt and a key. After reading, call the Decrypt method passing the crypted text and the secret key.

string cryptedUser = Encrypt(user, "your_secret_key_ABCDEFG");
....

public string Encrypt(string stringToEncrypt, string key)
{
    if (string.IsNullOrEmpty(stringToEncrypt))
        throw new ArgumentException("An empty string value cannot be encrypted.");
    if (string.IsNullOrEmpty(key))
        throw new ArgumentException("Cannot encrypt using an empty key.");

    CspParameters cspp = new CspParameters();
    cspp.KeyContainerName = key;
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cspp);
    rsa.PersistKeyInCsp = true;
    byte[] bytes = rsa.Encrypt(UTF8Encoding.UTF8.GetBytes(stringToEncrypt), true);
    return BitConverter.ToString(bytes);
}

string clearText = Decrypt(cryptedText, "your_secret_key_ABCDEFG");
....

public string Decrypt(string stringToDecrypt, string key)
{
    string result = null;
    if (string.IsNullOrEmpty(stringToDecrypt))
        throw new ArgumentException("An empty string value cannot be encrypted.");
    if (string.IsNullOrEmpty(key))
        throw new ArgumentException("Cannot decrypt using an empty key");
    try
    {
        CspParameters cspp = new CspParameters();
        cspp.KeyContainerName = key;
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cspp);
        rsa.PersistKeyInCsp = true;
        string[] decryptArray = stringToDecrypt.Split(new string[] { "-" }, 
                                 StringSplitOptions.None);
        byte[] decryptByteArray = Array.ConvertAll<string, byte>
                                 (decryptArray, (s => Convert.ToByte(byte.Parse(s,
                                 System.Globalization.NumberStyles.HexNumber))));
        byte[] bytes = rsa.Decrypt(decryptByteArray, true);
        result = System.Text.UTF8Encoding.UTF8.GetString(bytes);
    }
    finally
    {
        // no need for further processing
    }
    return result;
}

Of course, I assume that the security level required by your application allows that username ans passwords will be stored in the local system. (And as you know, everything that is stored on the local system is not very secure)



回答2:

Check this tutorial with read, write and delete function for registry

Read, write and delete from registry with C#



回答3:

Here is a good tutorial that will explain read/write to registry.

http://www.switchonthecode.com/tutorials/csharp-snippet-tutorial-editing-the-windows-registry

There are few more things you need to know about registry.

  1. Registry consists of five sections of which HKEY_CURRENT_USER stores the settings of currently logged in user. It is recommended that you store the settings under this key. Settings are stored generally in HKEY_CURRENT_USER/Software//

  2. You can store machine wide settings (applicable to all users using the computer) under HKEY_LOCAL_MACHINE key. However, read/write operations to this requires administrative rights. Your application must be running in administrator privilege to write to this key.

  3. Make sure that your registry reading mechanism returns default values if it is not found in the registry as well as write the default values to registry. This way, you will never run out of setting values.

  4. Registry can be edited and can be read. If you are planning to store username/password combination in registry, make sure you encrypt it before you store it. Further, to make sure that it is not used on any other computer also, you should encrypt it with some machine specific information.

Hope this helps you.



回答4:

You could try using IsolatedStorage. MSDN Blurb, code sample, and (given you're storing user credentials) an encryption sample. I've linked .net 2.0 samples where possible.

Storing application data in the registry has become unpopular since there are easier alternatives and using the registry can hurt the performance of your users' computers.



回答5:

I've never used the registry but first thing that comes up on google is this. Seems like fairly easy to understand so have fun with it :)



回答6:

doing it the registry way is the wrong way to go, , i believe do a config file and read this config is much better way to go. but anyway here how you do registry thing

http://www.codeproject.com/Articles/3389/Read-write-and-delete-from-registry-with-C



回答7:

You need to ask yourself a couple of questions:

  1. Should only one user be able to use the uid/password?

  2. How safe should the password be stored?

It's quite easy to store information in the registry. http://msdn.microsoft.com/en-us/library/microsoft.win32.registry.aspx

If you just want to store it for one user, store it under HKEY_CURRENT_USER/software/your_company/your_product otherwize store it under HKEY_LOCAL_MACHINE/software/your_company/your_product.

If your password is to be stored safely, there are safer solutions than the registry.