C#,如何检查文件是否正确

4

我有一个C#程序,其中有一个文件用于读写一些信息。我需要用户无法更改该文件的内容,我需要一种方法来检查该文件是否正确(未被用户更改)。如果您有任何想法,请写下来,我们一起讨论。


文件和它的副本有什么不同? 校验和、CRC、哈希还是其他? - Armen Khachatryan
6个回答

5
计算文件的 校验和 循环冗余校验 (CRC) 哈希值 并将其写入文件本身(在写出哈希值之前计算哈希值)。 然后当您加载文件时,检查此哈希值是否存在,删除它并重新计算哈希值。验证它们是否匹配。如果不匹配,则已被篡改。 每次更改文件内容时,请更新校验和/哈希值。

1
请记住,用户将能够修改文件并在以后替换文件中的哈希,以防止检测到修改。 - AaronLS
谢谢,但是有时候当用户复制文件后,会继续使用原始文件并覆盖已复制的文件,导致从头开始工作。我不希望发生这种情况,所以需要在文件中写入时间信息... - Armen Khachatryan
文件和它的副本有什么不同? 校验和、CRC、哈希还是其他? - Armen Khachatryan

2
没有一种完全可靠的方法可以实现你想要的。如果对文件进行哈希,用户可以修改文件并重新生成哈希值,然后你的程序将认为文件未被修改。如果试图将哈希隐藏在注册表中,用户可以轻松使用SysInternals工具检测到你保存它的位置。
相反,你可以数字签名文件,这类似于对其进行哈希,但涉及秘密密钥。然而,你仍然面临一个问题,即密钥必须保密,将其存储在应用程序或计算机上的某个地方会留下用户定位密钥的潜力,然后他们可以修改文件并重新签名,使得修改无法被你的程序检测到。
你可以让应用程序提交文件或者仅提交文件哈希(为了提高效率)到你创建的Web服务。Web服务可以数字签名文件或哈希,并返回签名或将其存储在服务器上。稍后当应用程序读取文件时,它可以使用签名和服务器的公钥(你必须从服务器获取此公钥以确保文件已由服务器签名)来验证文件是否未被更改。或者,如果服务器存储了签名,你可以重新提交文件或哈希到服务器,它可以验证文件并向应用程序返回结果。同样,这也不是绝对可靠的。即使使用SSL,用户也有办法规避它,用户完全可以破解你的应用程序并删除验证代码。
从你的其他问题来看,这是软件激活系统的某个组件。只需要看看Adobe和Microsoft以及他们失败的尝试来创建这样一个系统。如果你认为自己能做得更好,祝你好运。有更好的方法可以确保你的软件在没有激活系统的情况下合法使用,而不会让忠实的用户感到沮丧。

是的,你判断得对,我想为我的程序制作一个演示。谢谢你的回答,请告诉我更好的方法,我希望最大限度地让我的忠实用户失望... - Armen Khachatryan
用户复制文件,有时与文件一起工作,然后替换已复制的文件,并从零开始工作。我不想这样。在文件中写入时间信息... - Armen Khachatryan
文件和它的副本有什么不同? 校验和、CRC、哈希还是其他? - Armen Khachatryan
企业通常不会使用非法软件,因为这会带来法律风险。对于演示,我需要用户在我的网站上注册并提供联系信息,然后通过提供的电子邮件发送下载链接。演示期结束后,请让您的销售部门联系他们,询问他们是否有兴趣购买该软件,因为他们的试用已经结束。 - AaronLS

0
如果您只需要在C#中以只读方式打开文件,可以通过指定FileAccess.Read标志来实现:
using (FileStream fs1 = new FileStream(path, FileMode.Open, FileAccess.Read))
{
    using (StreamReader rd1 = new StreamReader(fs1))
    {
        while ((str = rd1.ReadLine()) != null)
        {
            //do stuff
        }
    }
}

0
你可以使用哈希来确保文件没有改变?
public static void Main(string[] args)
{
    using (HashAlgorithm hashAlg = new SHA1Managed())
    {
        using (Stream file = new FileStream("C:\\test.txt", FileMode.Open, FileAccess.Read))
        {
            byte[] hash = hashAlg.ComputeHash(file);
            Console.WriteLine(BitConverter.ToString(hash));
        }
    }
}

或者

BitConverter.ToString(MD5.Create().ComputeHash(File.ReadAllBytes("C:\\test.txt")))

0

了解一下MD5哈希算法。


0

你不能限制用户在文件系统中操作,但你的应用程序可以存储文件参数(创建和修改时间戳,大小)并对其内容创建哈希值,以便在下次使用文件之前与这些值进行比较。

更新:

如果你想避免用户以任何方式修改文件,你必须限制他们除了读取之外的访问权限。所以你有两个选择:

  1. 使用安全授权并从访问控制列表 (ACL) 中删除用户。如果用户是管理员,那么这是一个糟糕的主意。其他情况下,最好定义一些用户组(如果可能的话)。
  2. 使用数据库。这可以是一种轻量级的本地数据库,只有高级用户才能修改,例如 SQLite。但这仅适用于用户无法打开此文件(无法安装适当的工具...)的假设条件。

好的,非常好,你完全理解我的意思。但是,要把哈希结果保存在哪里呢?我尝试将其保存在注册表中。但是用户可以从注册表中复制哈希结果,然后将文件粘贴到注册表中,这样文件就可以从零开始工作一段时间。我不想让这种情况发生... - Armen Khachatryan
@Armen psychotik的回答涵盖了这个任务。 - terR0Q
用户复制文件,有时与文件一起工作,然后替换已复制的文件,并从零开始工作。我不想这样。在文件中写入时间信息... - Armen Khachatryan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接