20

我的场景是我们有一个程序(exe),如果在特定文件夹中找到它,它将启动其他程序。我想确保它只启动使用我们的公司证书(Verisign 批准等)签名的程序。本质上,它只会使用与自身相同的证书启动程序。我不想发送证书本身。

我一直在搜索网络和系统命名空间,但没有找到一个清晰的示例,它可以从文件中读取证书数据并对其进行验证,并且可以检查另一个文件。我发现的最接近的是Signtool,并且在单独的exe中进行此验证有点少。我知道强命名的东西不会有帮助,因为数字签名的文件是不同的,正如这里有用的解释(http://blog.codingoutloud.com/2010/03/13/three-ways-to-tell-whether-an-assembly- dl-is-strong-named/) 还有一些 SO 中的其他示例显示了原始数据的加密和验证,但不是以某种方式将其打包在一起的程序集。

有什么想法或建议吗?

4

4 回答 4

18

这是一篇博客文章,其中包含有关如何验证程序集签名的代码示例:http:
//blogs.msdn.com/b/shawnfa/archive/2004/06/07/150378.aspx

最后的代码示例显示了如何验证程序集是否由 Microsoft 签名 - 您可以通过获取公司证书的证书令牌来执行相同操作。

更新:用户@Saber 使用以下更新对此进行了编辑,但该更新被其他人拒绝。但是,这是非常有效的建议,所以我重新发布他/她的编辑,因为 SO 不会让我批准它:

编辑(谢谢,OP):如果您想更安全地执行此操作(即使您的程序更防篡改),请在您的程序中引用一个使用相关密钥强命名的程序集,然后使用引用程序集的令牌与调用程序集的令牌进行比较。如果您使用字节数组(根据链接),它可以简单地进行十六进制编辑和更改。

于 2011-02-16T09:48:40.437 回答
3

.NET 程序集存在两种签名技术:strongnaming 和 Authenticode(authenticode 用于对 PE 和其他一些文件进行签名,而不仅仅是 .NET 程序集)。它们用于不同的目的。Authenticode 中的证书仅用于对作者进行身份验证。强命名根本不验证作者。

除了检查签名之外,还必须验证证书以确保它是为给定作者颁发的。正确验证是一个复杂的过程,涉及 CRL(证书撤销列表)和 OCSP(在线证书状态)检查。

要执行 Authenticode 签名验证,您需要 Authenticode 验证组件。一种选择是使用我们的 SecureBlackbox 产品的PKIBlackbox包。该软件包包括 Authenticode 验证以及完整的证书验证机制。

请注意,如果您不打算验证证书,那么验证签名根本没有意义,因为可以创建具有相同主题、序列号等的自签名证书,并使用它来签署伪造的程序集。

于 2011-02-16T07:02:01.990 回答
3

您可以在这里尝试三个选项。

1)第一个是使用像这里这样的装配负载:

Assembly myDll =
    Assembly.Load("myDll, Version=1.0.0.1, Culture=neutral, PublicKeyToken=9b35aa32c18d4fb1");

您可以使用以下强名称 (Sn.exe) 命令打印特定程序集的公钥和公钥令牌的十六进制格式:

sn -Tp <assembly>

如果您有公钥文件,则可以改用以下命令(注意命令行选项的大小写差异):

sn -tp <assembly>

2)这里提到了第二个。并使用 p/Invoke 解决此类问题。

3) 还存在第三种、更敏捷、更复杂的方式来执行此操作。这是一个约束策略。当您应该为已部署的应用程序提供升级时,您可以将其考虑在内。当您的应用程序可以受益的共享组件的新版本出现时,应用程序策略文件将允许您提供这些好处,而无需重新编译或替换现有安装。

您可以在此处找到有关此功能的更多信息:

http://msdn.microsoft.com/en-us/library/aa309359%28v=vs.71%29.aspx

http://ondotnet.com/pub/a/dotnet/2003/03/17/bindingpolicy.html

于 2011-02-16T09:06:31.707 回答
0

我相信有一种方法可以使用强名称来达到“信任”的目的。我了解 Microsoft 仅建议使用强名称以确保程序集内容未被修改,并建议使用“Authenticode”来获得信任。

但是,如果加载器应用程序(加载这些程序集/程序的应用程序)维护它可以加载的“程序集”的加密列表;那不会解决“信任”问题吗?

例如,包加载器可以使用公钥维护程序集名称并通过完整的程序集名称加载程序集/程序?

<PackageHandlers>
  <PackageHandler>
    <Package type="Package1" assembyName="SomeAssembly" publickey="d45755dbb8b44e59" />
  </PackageHandler>
</PackageHandlers>
于 2016-07-22T16:50:41.500 回答