c# - 如何在 .NET 中验证 DLL 的数字签名

标签 c# .net security dll dllimport

我编写了一个 C# .NET 应用程序,它使用流行的非托管 DLL 文件来实现其部分功能。 DLL 是使用来自 System.Runtime.InteropServices 的标准 DllImport 导入的。

但是,不幸的是,我的应用程序(以及大多数使用 DllImport 的 .NET 应用程序)容易受到 DLL 劫持。 IE。攻击者可以将导入的 DLL 的恶意副本放置在与我的应用程序打开的任何文件相同的目录中。 这可能会让攻击者完全控制用户的机器。

为了缓解此漏洞,我想在导入 DLL 文件之前验证它是否已正确签名(使用默认 Authenticode)。 我知道可以使用 sigcheck.exe 等工具验证签名,但这对我来说不是一个可行的解决方案,因为我需要在我的 C# 代码中执行此操作。

所以我的问题很简单:在加载 DLL 之前,如何从我的托管 C# 代码中验证 DLL 是否具有有效的 Authenticode 签名?

限制:

  • 导入的 DLL 不是我开发的,它来自外部公司。
  • DLL 未随我的应用程序分发,预计在运行我的应用程序之前已安装。
  • 导入的 DLL 有很多不同的版本(以后还会有更多),所以我不能简单地 verify an MD5 checksum of the DLL在导入之前。

失败的方法:

  • Microsoft 在 preventing "DLL preloading attacks" 上有一篇很好的文章, 但是,此信息不适用于 .NET 的 DllImport。
  • 我看到有人建议使用 Wintrust.dll 中的非托管函数 WinVerifyTrust。 这当然是一个愚蠢的解决方案,因为这反而会使我的应用程序容易受到通过 Wintrust.dll 进行的 DLL 注入(inject)攻击。

最佳答案

您需要使用 Authenticode 验证程序。 this question的答案提供使用 P/Invoke 如果您需要托管解决方案,您可能会对我们的 SecureBlackbox 感兴趣库,除其他功能外,还提供 Authenticode 签名和签名验证。

但是,虽然您可以保护自己免受加载虚假 DLL 的侵害,但您无法保护应用程序本身免遭破解。因此,签名验证当然只能保护您免受一种攻击。

让我指出,替换 WinTrust.dll 取决于需要访问计算机的不同攻击媒介。在这种情况下,攻击者可以完全修补您的应用程序。

关于c# - 如何在 .NET 中验证 DLL 的数字签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17766592/

相关文章:

c# - 检查表单是否加载

c# - 线程正在退出

.net - 重新排序 wsdl :definitions in an ASP. NET Web 服务

c# - 从 C# 代码动态切换 WPF 网格列的可见性

.net - 我的 URL 中问号的名称是什么?

c# - 只读字典 - 多线程调用 .ContainsKey 方法

java - Jersey REST-Servlet 中的 RolesAllowed 注释不起作用

java - 将签名的小程序集成到 Java Web 应用程序中

security - 检查引荐来源网址是否足以防范 CSRF 攻击?

c# - Microsoft Graph API 查询适用于 Explorer,但不适用于 Microsoft Graph .NET 客户端库