如何以编程方式验证程序集是否使用特定的证书进行签名?

问题描述:

我的方案是我们有一个程序(EXE),将启动其他程序,如果在一个特定的文件夹中找到。我想确保它只启动与我们的公司证书(Verisign批准等)签署的程序。从本质上讲,它只会启动与自身具有相同证书的程序。我不想出示证书本身。如何以编程方式验证程序集是否使用特定的证书进行签名?

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

任何想法或建议吗?

这里有一个博客帖子上如何验证汇编签名代码示例:
http://blogs.msdn.com/b/shawnfa/archive/2004/06/07/150378.aspx

代码最后的示例演示了如何验证程序集是否由Microsoft签署 - 您也可以通过获取您公司证书的证书令牌。

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

编辑(谢谢你,OP):如果你想要更安全地做到这一点(即做您的程序更具防篡改性),在您的程序中引用与相关密钥强烈命名的程序集,然后使用引用程序集的标记与调用程序集的标记进行比较。如果您使用字节数组(按照链接),它可以简单地进行十六进制编辑和更改。

+4

为什么downvote? _阅读我链接到的博客文章,您将看到它确实显示了强大的命名链接到程序集签名中,并且您可以使用它来验证程序集是否已使用特定证书签名。 – KristoferA 2011-02-17 02:59:48

存在两种签订技术.NET程序集:strongnaming和验证码(验证码用于签名PE和其他一些文件,而不只是.NET程序集)。它们被用于不同的目的。 Authenticode中只使用证书来验证作者。强化并没有对作者进行认证。

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

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

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

你可以试试这里是三个选项。

1)第一种是使用的组件负载喜欢这里:

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

您可以通过以下强名称(SN打印特定程序集的公钥和公钥标记的十六进制格式。 EXE)命令:

sn -Tp <assembly> 

如果你有一个公共密钥文件,可以使用下面的命令来代替(注意如果在命令行选项的区别):

sn -tp <assembly> 

2)第二个is mentioned here。并使用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

我相信有一种方法可以将强名称用于“信任”的目的。我明白微软只会建议强名,以确保程序集内容未被修改,并建议使用“Authenticode”作为信任。

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

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

<PackageHandlers> 
    <PackageHandler> 
    <Package type="Package1" assembyName="SomeAssembly" publickey="d45755dbb8b44e59" /> 
    </PackageHandler> 
</PackageHandlers>