Converting Registry data to usable String in C#

Viewed 212

So I'm currently creating a CLI program for my encryption library. This is just a test program, as I will later build a GUI-based program for it. I am storing the encryption key in the registry, for now, might change this later. So far, I can write the key to the registry, but I can't convert the data from the registry back to a string to use as the actual key in the encryption.

Here's my current code:

internal String Encrypt()
        {
            Console.Clear();
            Console.Write("Encryption\nPlease enter the path to the file you want to encrypt: ");

            String FileInPath = Console.ReadLine();
            String FileOutPath = "";
            String FileData = "";

            while (FileInPath == "")
            {
                FileInPath = RetryPathIn();
            }

            String RetryPathIn()
            {
                Console.WriteLine(".>>");
                String PathInStr = Console.ReadLine();
                return PathInStr;
            }
            
            Console.Write("\nPlease enter the path of the file you want to decrypt: ");
            FileOutPath = Console.ReadLine();

            while (FileOutPath == "")
            {
                FileOutPath = RetryEncrypt();
            }

            String RetryEncrypt()
            {
                Console.WriteLine(".>>");
                String FileOutPathStr = Console.ReadLine();
                return FileOutPathStr;
            }
            object Key = Registry.CurrentUser.OpenSubKey(@"Software\NikkieDev Software").GetValue("Key");
            String KeyStr = Key.ToString();
            String FileOutData = "";

            if (Key!=null)
            {
               FileOutData = Crypt.Encrypt(FileData, KeyStr);
            }

            var file = File.Create(FileOutPath);
            file.Close();
            File.WriteAllText(FileOutPath, FileOutData);

            return $"Data has been encrypted and saved in {FileOutPath}";
        }

I am fairly new to the registry, and I've only recently found out how to use it as data storage in programming. I am using .NET 6 for this, and I hope that someone can help me.

[EDIT] I've shown below how I've created the register data. Due to people asking about it

internal void Initialize()
        {
            String SettingsFile = File.ReadAllText(CoreObject.DataFile);
            dynamic _JsonObj = JsonConvert.DeserializeObject(SettingsFile);

            if (_JsonObj["KeyGenerated"] == 0)
            {
                RegistryKey RegData = Registry.CurrentUser.CreateSubKey(@"Software\NikkieDev Software");
                String NewKey = Key.CreateKey();
                RegData.SetValue("Key", NewKey);
                
                _JsonObj["KeyGenerated"] = 1;

                dynamic NewData = JsonConvert.SerializeObject(_JsonObj, Formatting.Indented);
                File.WriteAllText(CoreObject.DataFile, NewData);
                RegData.Close();
            }
        }

Due to recent questions about missing code, I here provide my encryption library that I'm building this program around: https://github.com/NikkieDev/bungocrypt_cs

The CreateKey() returns a string (the key). Furthermore Crypt.Encrypt() takes the key and the data and scrambles them together and exchanges all the characters with one another.

1 Answers

Nikkie, your code works just fine.

You are using the Registry API correctly, and running your code the key has the correct string value (tested with dotnet6 on windows11). Here is my output adding a print:

Generated key: HYO"kjvw'l.K2IDu:*Mt-ze~=/,Ls6Zgf_]WSc[<F7Q185@NTB?^rxP)J#p$4VX q(&nh!Go\3Ci|a}EdR{+;b9>`0AyUm%
Key value from reg: HYO"kjvw'l.K2IDu:*Mt-ze~=/,Ls6Zgf_]WSc[<F7Q185@NTB?^rxP)J#p$4VX q(&nh!Go\3Ci|a}EdR{+;b9>`0AyUm%

Do not forget to always close the key when you do not need it anymore (well done in your initialization, but not done after). Close the RegistryKey as soon as you can. For instance in your Initialize function, it would be better to close the key before doing your JSON serialization and IO as some exceptions may occur there.

An other point, regData.SetValue will definitely accept empty string (but will throw if null is given). So this can also be a way to debug if you have the same problem again, somewhere you might be writing something empty as mentioned in comments.

Some recommendations as you are saying that you are new on some concepts:

  1. Strongly recommended to check for nullity. For instance Registry.CurrentUser.OpenSubKey may return null. You do want to check that before continuing.

  2. Instead of using Key.ToString(), what you will prefer is String KeyStr = (String)Key or String? KeyStr = Key as String. In the first one, an exception will be thrown if the cast is not possible. In the second one, do not forget to check for nullity if the cast can't be done.

  3. Starting with dotnet6, try to use the built-in JSON serializer in System.Text.Json which is fairly nice now, and has very nice options to customize serialization behavior.

  4. I strongly recommend that you read the security part of this documentation from Microsoft, as you are planning to continue working with cryptography and keys. I don't know the exact scope of your keys, but it's a good reading anyway.

Related