我是否需要从.snk文件发布公钥?

时间:2009-04-28 15:47:28

标签: .net assemblies strongname

从sn.exe实用程序和this question的描述中,我看到公共密钥的副本被添加到使用强名称签名的每个程序集中。这足以验证汇编二进制文件是否未被更改。

但是,如何验证给定的程序集是否真的使用某个给定的密钥对签名并由给定的公司编译?任何人都可以生成他自己的密钥对,生成一些程序集并用他的密钥对签名。我是否需要发布公钥,以便那些想要验证程序集来源的人可以比较公钥?如果是这样,最好的方法是什么?

3 个答案:

答案 0 :(得分:5)

不,您不需要在程序集之外发布公钥,因为它是在客户端应用程序内的引用旁边进行哈希处理并存储为令牌:

AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bcd6707151635d07"

这提供了一种方法来确保程序集的所有未来版本都是针对相同的密钥对进行编译的,因此也是来自同一个发布者的。

如何让这些信息阻止其他来源假装成你的更多细节可以在我的其他答案中找到。

答案 1 :(得分:3)

我始终了解将程序集签名为运行时检查的目的,以确保代码的升级来自可信来源。实际上,他们正试图避免这种情况:

我从A公司购买了一个加密库,不久之后,B公司获取了我的电子邮件详细信息并向我发送了一个免费的升级程序,假装是公司A的一个主要安全漏洞修复程序,当它真正注入一个隐藏的方法时我的代码将我尝试加密的所有数据发送到公司B的服务器。假设我是一个白痴并且盲目地将这个新的dll添加到我的应用程序的bin目录中,那么这个未使用与旧版本相同的私钥签名的事实将在运行时被选中,从而导致异常并保护我的数据。 / p>

所以,我认为你没有理由在公会之外发布公钥,因为它不应该保证原始文件来自特定供应商,只是所有后续版本都来自同一个地方。第一

Wikipedia说了很多相同的话(只有少得多的单词)。


编辑以添加更多信息,以使此更清晰......

我认为需要首先澄清的是公钥和私钥对是唯一的。这意味着知道公钥不足以重新组装程序集,因为它将传递相同的哈希检查。

所以正在使用公司A加密库的用户Z在他的应用程序bin文件夹中。为此,他按如下方式引用DLL:

Encryption, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bcd6707151635d07"

公钥的目的是向我们提供three benefits,我将一次处理一个。

首先,它为程序集提供了一个唯一的名称 - 这给了我们没有额外的安全性但是停止C风格的dll Hell,两个不同的公司可以发布两个名为Encyption版本1.0.0.0的不同库,你将无法将它们存储在同一目录中,因为无法区分它们。

其次,它会阻止我在原帖中概述的场景。公司B不可能创建另一个版本的加密库,它也是版本1.0.0.0并具有相同的公钥(因此整个名称将匹配,您将调用其代码而不是公司A)。他们不能这样做,因为如果他们的公钥匹配,那么私钥也必须匹配(因为每个是唯一的)。他们获得私钥的唯一方法就是损害A公司的安全性。

最后,它确保文件的完整性(通过损坏或恶意代码注入来更改)。 dll在运行时进行哈希处理(当它是私有的并且在应用程序的bin文件夹中)或使用公钥安装时间(当你将它放入GAC时),并将哈希与私有加密的哈希进行比较键并存储在程序集中。 This page有一些图表和更多细节。再次伪造此哈希的唯一方法是知道私钥。

因此,为了涵盖我上面描述的特定场景,假装我是B公司试图向用户Z提供恶意版本的加密dll。我的第一个尝试是使用名称Encryption和Version 1.0.0.0创建自己的dll,并使用我自己的密钥对进行签名。不幸的是,我无法更改User Z的应用程序中的参考代码,因此它未通过全名检查而且未加载。 “好吧,”我在旋转胡须时说道,“我只是改变我的装配公钥,以匹配公司A的公钥”。完成此操作后,名称检查将通过,但哈希检查将失败,因为用户Z的应用程序将无法使用公钥(公司)解密存储在程序集中的哈希(使用公司B的私钥加密) A)已经提供。因此,B公司创建假装成公司A的图书馆的唯一方法是了解公司A的私钥。这些安全检查都不依赖于公司A在其他任何地方发布公钥,而是在程序集的原始版本中发布。

另请注意,所有这些功能都不能确保(并且不声称确保)原始程序集来自公司A,这是由其他系统(如Verisign或Microsoft的{{3)处理的} service,它们只确保一旦引用了程序集,只有A公司可以对该代码进行更改。

答案 2 :(得分:2)

  1. 您可以前往某个3D派对证书提供商(例如VeriSign)并从他们那里购买证书(Code Signing At Verisign)。
  2. 您使用具有公司名称,网址等的授权证书来签署您的代码。
  3. 我下载了您的应用,并查看您的应用已签名的证书列表。
  4. 我使用您的证书,返回VeriSign并验证证书是否确实已发给MyCompany,LLC。
  5. 我查看用于颁发证书的证书,并验证VeriSign是否为其中之一(Windows附带了少量可信证书)。
  6. <强>要点:
    您不仅要验证代码是否未被修改,还要使用您信任的一方颁发的证书进行签名。