简体   繁体   English

将用户凭据存储在 c# 的本地文件中

[英]Store user credentials in a local file in c#

I am developing an app in C# .NET.我正在 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.我想将用户数据存储在本地文件中,例如文本文件或平面文件或 JSON 文件。

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 ð} ¥CP~ ¸C 0 ËC ÞC € ñC € D D ‚ *D °ƒ =D „ ND就像谷歌浏览器存储数据的方式一样: 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 ð} ¥CP~ ¸C 0 ËC ÞC € ñC € D D ‚ *D °ƒ =D „ ND

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:来自 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);
        }
    }
}

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM