繁体   English   中英

如何创建只有我的应用程序才能修改的文件?

[英]How can I create a file that only my application can modify it?

如何创建只有我的应用程序才能修改的文件? 我需要它,因为我有一个应用程序可以创建一个存储用户信息的.txt文件,并且我不希望用户能够通过文件资源管理器对其进行修改,但我的应用程序应该能够创建、修改它并删除它。

这是我的代码:

        public void Write(List<Queue> Queue)
        {
          try
          {
            CreateFile();
            using (FileStream Stream = new FileStream(Path, FileMode.Open))
            {
                using (StreamWriter file = new StreamWriter(Stream))
                {
                    string Data = JsonSerializer.Serialize(Queue);
                    file.Write(Data);
                    file.Flush();
                    file.Close();
                }
            }
        }
        catch (IOException ex)
        {
            Log.GetInstance().Write(ex.Message);
        }



public void CreateFile()
    {
        if (!FileExist)
        {
            File.Create(Path).Close();
        }
    }

    public List<Queue> ReadFile()
    {
        try
        {
            if (FileExist)
            {
                using (StreamReader file = new StreamReader(Path))
                {
                    string Data= file.ReadToEnd();
                    return JsonSerializer.Deserialize<List<Cola>>(Data);
                }
            }
        }
        catch (JsonException ex)
        {
            Log.GetInstance().Write(ex.Message);
        }
        catch (IOException ex)
        {
            Log.GetInstance().Write(ex.Message);
        }
        return null;
    }

据我所知,你不能。 无论哪种方式,用户和/或管理员都可以访问该文件。 但是,您可以通过散列文件并将散列与文件进行比较来检测修改

您可以加密文件以防止篡改。 好吧,至少任何篡改都会损坏文件。

CLR 有一种机制可以为特定用户加密数据,而无需单独生成和存储密钥。 这使用了System.Security.Cryptography中的ProtectedData.Protect()ProtectedData.Unprotect()机制。

这是一个测试程序。 运行它,选择 1 存储数据,输入一些秘密然后退出。 再次运行,选择2读取数据,就会出现密文。

class Program
{
    static void Main(string[] args)
    {
        while (true)
        {
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.WriteLine("Do you want to 1. store data, 2. read data or 0. exit ?");
            Console.ForegroundColor = ConsoleColor.Gray;
            var input = Console.ReadLine();

            if (input.Length == 0 || input[0] == '0') break;

            if (input[0] == '1')
            {
                Console.WriteLine("Type in a very secret message to store:");
                Console.ForegroundColor = ConsoleColor.Yellow;
                var text = Console.ReadLine();
                Console.ForegroundColor = ConsoleColor.Gray;
                if (text.Length > 0)
                {
                    WriteToFile(text);
                }
            }

            if (input[0] == '2')
            {
                if (ReadFromFile(out string text))
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine(text);
                    Console.ForegroundColor = ConsoleColor.Gray;
                }
            }
        }
    }

    const string filename = "data.enc";

    static bool WriteToFile(string text)
    {
        var fn = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), filename);
        var data = Encoding.Unicode.GetBytes(text);
        try
        {
            var cipher = ProtectedData.Protect(data, null, DataProtectionScope.CurrentUser);
            File.WriteAllBytes(fn, cipher);
            Console.WriteLine($"Encrypted {data.Length} bytes in {fn}.");
            return true;
        }
        catch (CryptographicException ex)
        {
            Console.WriteLine("Error encoding data: ");
            Console.WriteLine(ex.ToString());
        }
        catch (IOException ex)
        {
            Console.WriteLine("Error creating file: ");
            Console.WriteLine(ex.ToString());
        }
        return false;
    }

    static bool ReadFromFile(out string text)
    {
        var fn = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), filename);
        try
        {
            var cipher = File.ReadAllBytes(fn);
            var data = ProtectedData.Unprotect(cipher, null, DataProtectionScope.CurrentUser);
            text = Encoding.Unicode.GetString(data);
            Console.WriteLine($"Decrypted {data.Length} bytes from {fn}.");
            return true;

        }
        catch (CryptographicException ex)
        {
            Console.WriteLine("Error decoding data: ");
            Console.WriteLine(ex.ToString());
        }
        catch (IOException ex)
        {
            Console.WriteLine("Error reading file: ");
            Console.WriteLine(ex.ToString());
        }
        text = null;
        return false;
    }
}

scr1

并且data.enc的内容是完全加密的:

scr2

如何创建只有我的应用程序才能修改的文件?

你不能。 就那么简单。

问题是管理员可以访问所有文件。 以及与您一起运行您的应用程序的用户。 当然还有黑客。 ;) 通常,您只需将应用程序文件存储在一些完善的位置,例如,将应用程序文件放在 unix 系统中的/var/lib/myapp中是事实上的标准。 当然,其他用户仍然可以访问这些文件,但这样至少可以降低意外修改的风险。 然而,这也意味着您永远不应该在本地存储敏感数据

加密并不是一个真正的选择,因为您必须将加密密钥存储在某个地方,这只会将一堆从一个地方移动到另一个地方。 它确实使读/写变得更加困难,但并不能真正解决问题。 除非您不将密钥存储在任何地方,例如您在应用程序启动时手动提供它,或者在运行时更好地提供它,并且您确保它不会存活太久。 根据您的用例,这可能是一个有效的选项。

修改检测,即散列文件,具有完全相同的问题:您必须将散列存储在某处。 您只强制恶意用户修改两个位置而不是一个。

请注意,在本地使用数据库引擎根本没有帮助。 归根结底,数据库只是一个花哨的文件,您仍然需要在某处存储访问密钥。

总而言之:如果您要存储非敏感数据,请将其放在应用程序数据文件夹中,不要担心。

不确定您的应用程序应该做什么,但实现此目的的方法是在计算机上创建一个新用户或组并以该用户身份运行您的应用程序。 然后,您可以使用SetAccessControl使用户或组具有读/写权限,而其他所有人都具有读权限。 这实际上应该是一个 Windows 服务而不是一个应用程序。

暂无
暂无

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

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