Home > Enterprise >  Store user credentials in a local file in c#
Store user credentials in a local file in c#

Time:02-04

I am developing an app in C# .NET. The app will not connect to any database and during the installation it will create files and settings for the application and user. I want to store user data in a local file such as text file or flat file or JSON file.

In simple words I want to prevent user opening the file but if somehow user find a way to open it then at least he should not understand what information is stored. Is there any good method to encrypt file and data in it?

Just like how Google chrome stores data: 1 ŒA û œA àû ¯A ü ÂA °ü ÒA ý åA Pý õA À% B & B p& (B °m <B n OB ðn bB Po uB °o ˆB q ›B Àq ®B r ÁB €r ÔB s çB pt úB °u C @v C  v 3C x FC Àx YC  z lC P| C °| ’C ð} ¥C P~ ¸C 0 ËC ÞC € ñC € D   D ‚ *D °ƒ =D „ ND

CodePudding user response:

You can try encrypting the file and decrypt it when you need to access it.

Encryption Decryption

Example of encryption and decryption from MS Docs:

using System.IO;
using System.Security.AccessControl;

namespace FileSystemExample
{
    class FileExample
    {
        public static void Main()
        {
            try
            {
                string FileName = "test.xml";

                Console.WriteLine("Encrypt "   FileName);

                // Encrypt the file.
                AddEncryption(FileName);

                Console.WriteLine("Decrypt "   FileName);

                // Decrypt the file.
                RemoveEncryption(FileName);

                Console.WriteLine("Done");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            Console.ReadLine();
        }

        // Encrypt a file.
        public static void AddEncryption(string FileName)
        {

            File.Encrypt(FileName);
        }

        // Decrypt a file.
        public static void RemoveEncryption(string FileName)
        {
            File.Decrypt(FileName);
        }
    }
}

CodePudding user response:

I wrote a very simple text encryptor that you can use. Simply encrypt the text before storing it and decrypt it as you need it.

This will not stop someone who is willing to spend a little bit of time with a debugger, but just like locking your door it will keep honest people honest.

I also included some unit tests, feel free to remove them.

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;

namespace Encryption;
public static class SimpleEncryptor
{
    public static async Task<string> EncryptAsync(string cleartext, string password)
    {
        var hasher = SHA256.Create();
        var key = hasher.ComputeHash(Encoding.UTF8.GetBytes(password));

        using var aes = Aes.Create();
        aes.Key = key;
        aes.Padding = PaddingMode.PKCS7;
        var iv = aes.IV;

        var byteStream = new MemoryStream(10000);
        byteStream.Write(iv, 0, iv.Length);

        using var cryptoStream = new CryptoStream(
            byteStream,
            aes.CreateEncryptor(),
            CryptoStreamMode.Write);
        
        var encryptWriter = new StreamWriter(cryptoStream);
        await encryptWriter.WriteAsync(cleartext);
        encryptWriter.Close();        

        var bytes = byteStream.ToArray();
        var base64 = Convert.ToBase64String(bytes);

        return base64;
    }
    public static async Task<string> DecryptAsync(string ciphertext, string password)
    {
        var hasher = SHA256.Create();
        var key = hasher.ComputeHash(Encoding.UTF8.GetBytes(password));

        var encryptedArray = Convert.FromBase64String(ciphertext);
        var byteStream = new MemoryStream(encryptedArray);

        using var aes = Aes.Create();
        aes.Key = key;
        aes.Padding = PaddingMode.PKCS7;
        var iv = new byte[aes.IV.Length];
        var numBytesToRead = aes.IV.Length;
        var numBytesRead = 0;
        while (numBytesToRead > 0)
        {
            var n = byteStream.Read(iv, numBytesRead, numBytesToRead);
            if (n == 0) break;

            numBytesRead  = n;
            numBytesToRead -= n;
        }

        using var cryptoStream = new CryptoStream(
               byteStream,
               aes.CreateDecryptor(key, iv),
               CryptoStreamMode.Read);
        
        var decryptReader = new StreamReader(cryptoStream);
        var decryptedMessage = await decryptReader.ReadToEndAsync();
        
        return decryptedMessage;
    }
}


public class EncryptorTests
{
    [Test]
    [TestCase("How do you turn this on?", "Swordfish", "GHzrU6z5hsgb6HSJtMZyirEs11sHY/X4l5zElwxHz9jpIGA D9TAxv7SEU31/Jgb")]
    [TestCase("Orange you glad I didn't say banana?", "hunter12", "qqNFxhwKYkkYzsN0vDzWhQguZ7f9xc 60duZXQATAzQslRhJsn6lc691 yVR0SWJYDJUD9ZbezpW/v4vYi6qeA==")]
    [TestCase("Orange you glad I didn't say banana?", "hunter12", "TsjCbMOT4UKVi6L43Kkc0rMsl6IyeEfLBR3ruAsG APUjb1zesVLGA/B0yF4FkFV/j1Rc5B55ClZYHV2zoubBA==")]
    [TestCase("Your mother is rather fat.", "12345", "WD8e5E PtQ5kMqkPSIZa18pDutbqn8OroSU5utHFTuikbgIWLA4IRAHihrfiXrV6")]
    [TestCase("Yer' a wizard harry!", "Swordfish", "Z6tF/3iDTu72qTeVnKa8DZOsL5NFD9XfqJTWebANVrjQysm 8ps3Z9RuoJyenk30")]
    public async Task TestDecryption(string text, string password, string ciphertext)
    {
        var decoded = await SimpleEncryptor.DecryptAsync(ciphertext, password);

        Assert.AreEqual(text, decoded);
    }

    [Test]
    [TestCase("How do you turn this on?", "Swordfish")]
    [TestCase("Orange you glad I didn't say banana?", "hunter12")]
    [TestCase("Your mother is rather fat.", "12345")]
    [TestCase("Yer' a wizard harry!", "Swordfish")]
    public async Task TestEncryptAndDecrypt(string text, string password)
    {
        var ciphertext = await SimpleEncryptor.EncryptAsync(text, password);

        var decodedtext = await SimpleEncryptor.DecryptAsync(ciphertext, password);

        Assert.AreEqual(text, decodedtext);
    }
}
  •  Tags:  
  • Related