Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 验证当前正在运行的可执行文件_C#_.net_Hash_Cryptography - Fatal编程技术网

C# 验证当前正在运行的可执行文件

C# 验证当前正在运行的可执行文件,c#,.net,hash,cryptography,C#,.net,Hash,Cryptography,我正在寻找正确的方法来验证当前正在运行的可执行文件。 我已经找到了一种为当前正在运行的文件计算(SHA256)哈希的方法 问题是:我在哪里安全地存储这个散列?如果我将其存储在配置文件中,恶意用户只需计算自己的哈希并替换它。如果我将其存储在可执行文件中,则可能会使用十六进制编辑器覆盖它 我读到的一个建议是做一个不对称的加密(或者是去加密),但我该怎么做呢 要求可执行代码在不同的计算机上进行完全相同的哈希和en/解密,否则我无法正确验证。所有计算机都将运行相同的操作系统,即Windows XP(嵌入

我正在寻找正确的方法来验证当前正在运行的可执行文件。 我已经找到了一种为当前正在运行的文件计算(SHA256)哈希的方法

问题是:我在哪里安全地存储这个散列?如果我将其存储在配置文件中,恶意用户只需计算自己的哈希并替换它。如果我将其存储在可执行文件中,则可能会使用十六进制编辑器覆盖它

我读到的一个建议是做一个不对称的加密(或者是去加密),但我该怎么做呢

要求可执行代码在不同的计算机上进行完全相同的哈希和en/解密,否则我无法正确验证。所有计算机都将运行相同的操作系统,即Windows XP(嵌入式)

我已经签署了我所有的程序集,但我需要一些额外的安全性来成功通过我们的安全目标


对于那些知道的人来说,这与FPT_TST.1.3有关:TSF应向授权用户提供验证存储的TSF可执行代码完整性的能力。

所有评论,尤其是来自Marc的评论都是有效的

我认为最好的办法是查看authenticode签名——这就是它们的用途。要点是exe或dll是用证书签名的(在证书上加盖组织信息的戳记,很像SSL请求),而修改后的版本(理论上加上所有正常的安全警告)不能用同一证书重新签名

根据需要(我这样说是因为这个“安全目标”有点含糊不清——验证代码完整性的能力可以很容易地作为如何在windows资源管理器中检查文件的演练),这本身就足够了(windows具有从证书中显示发布者信息的内置功能)或者,您可以编写一个例程来验证authenticode证书

看到这一点,最上面的答案链接到一篇关于如何以编程方式检查authenticode证书的文章(当然是老文章)

更新

按照Marc的建议进行——如果需要进行自编程检查,即使这样也不够。可以修改可执行文件,删除检查,然后在没有证书的情况下部署。所以杀了它

老实说-宿主应用程序/环境确实应该有自己的检查(例如,需要有效的authenticode证书)-如果不修改代码非常重要,那么它应该有自己的步骤来执行。我想你可能真的在白费力气

只需为你的利益投入最少的精力,而不用太担心它所提供的实际安全性——因为我认为你是从一个不可能的角度出发的。如果有人真的有任何真正的理由想要破解你写的代码,那么不仅仅是一个小学生想要破解它。因此,任何可用的解决方案(评论中提到的解决方案等)都将很容易被颠覆

一句话一句话的最后一句解释我的“白鹅追逐”评论

遵循最薄弱环节原则-可执行文件的完整性仅与运行该可执行文件的主机的安全要求一样有效

因此,在现代Windows机器上,UAC已打开,所有安全功能已打开;例如,安装或运行未签名的代码非常困难。用户必须真正想要运行它。如果你把所有的东西都降到零,那就相对简单了。在植根的安卓手机上,很容易运行会杀死你手机的东西。这方面还有许多其他例子


因此,如果您的代码将部署到的XP嵌入式环境没有对其实际运行的运行时安全性检查(例如,所有应用程序都需要authenticode证书的策略),那么您将从一个继承了比实际应该提供的安全性级别更低的安全性的点开始。再多的安全原语和例程也无法恢复该功能。

自.NET 3.5 SP1以来,运行时未检查强名称签名。 当程序集是强名称时,我建议按代码检查签名。 将本机
mscoree.dll
与p/Invoke一起使用

private static class NativeMethods
{
      [DllImport("mscoree.dll")]
      public static extern bool StrongNameSignatureVerificationEx([MarshalAs(UnmanagedType.LPWStr)] string wszFilePath, byte dwInFlags, ref byte pdwOutFlags);
}
然后,您可以使用assemlby load事件并检查加载到(当前)应用程序域中的每个程序集:

AppDomain.CurrentDomain.AssemblyLoad += CurrentDomain_AssemblyLoad;

private static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
    Assembly loadedAssembly = args.LoadedAssembly;

    if (!VerifytrongNameSignature(loadedAssembly))
        // Do whatever you want when the signature is broken.
}

private static bool VerifytrongNameSignature(Assembly assembly)
{
     byte wasVerified = 0;

     return NativeMethods.StrongNameSignatureVerificationEx(assembly.Location, 1, ref wasVerified);
}

当然,有足够经验的人可以修补Assemby中的“检查代码”,或者简单地从程序集中删除强名称。

如果怀疑正在执行的可执行文件可能已被编辑,这是否也意味着他们可能已删除(否)验证步骤本身?您应该找出为什么强签名是不够的,然后尝试找到解决方法。使用不同的密钥对同一文件进行两次签名不会比使用一次签名更安全…@AlexeiLevenkov当然,具有足够访问权限的恶意用户只需在命令行中使用
SN-Vr
即可禁用that@MarcGravell我理解这个问题,但这是安全目标所要求的,这就是为什么我需要把它放在那里。我只需要指出:看,我们有它,它就在那里,所以它可以从列表中删除。你不能将校验和存储在可执行文件中,因为如果你这样做,校验和会改变。这是递归的。我建议将散列和RSA签名的散列放入外部文件中。RSA签名阻止用户创建的哈希。当然,恶意用户仍然可以拒绝校验和验证。所以,没有绝对安全的防弹方法。我已经看到了,但仍然不是我想要的。问题是,用户身份验证只在程序本身中完成(使用定制的智能卡),所以