.NET数字签名如何工作?

时间:2013-11-04 15:17:01

标签: c# digital-signature

我对.NET程序集的密钥签名工作方式感到困惑。我通过插入密码并生成.pfx文件,用强名称签署了我的.NET程序集。

这应该如何保护我的dll?有人能用简单的语言向我解释一下吗?我是数字签名的新手,你必须退一步才能让我明白这个

2 个答案:

答案 0 :(得分:34)

  

我是一位有数字签名的新手,你必须采取一大步才能让我理解这一点

好的,让我们退后一步,然后问一些更基本的问题。我会在每一个具有精确含义的词汇上加粗。

  

安全系统的目的是什么?

通过敌对方(敌对方针对成功攻击的威胁(盗窃)保护资源(一堆金币)小偷)试图利用漏洞(解锁窗口)。 (*)

  

.NET的代码访问安全性如何发挥作用?

这是.NET 1.0安全系统的草图;它相当复杂,或多或少被一个稍微简单的系统取代,但基本功能是相同的。

每个程序集都会向运行时提供证据。域管理员,计算机管理员,用户和应用程序域创建者均可以创建安全策略。策略是在存在某个证据时授予权限的声明。当程序集尝试执行潜在危险操作(即可能对资源构成威胁的操作)时,运行时要求授予该权限。如果证据不足以授予该权限,则操作将失败并发生异常。

例如,假设一个程序集提供了证据"我刚刚从互联网上下载了#34;并且该政策说"从互联网下载的代码获得运行和访问打印机的权限# 34;然后该代码尝试写入C:\Windows\System32。由于证据不足,未授予许可,因此操作失败。资源 - 系统目录的内容 - 受到保护,不会被篡改。

  

使用我从VeriSign获得的数字证书签署程序集的目的是什么?

使用数字证书签名的程序集向运行时提供证据,说明用于对程序集进行签名的证书。管理员,用户或应用程序可以修改安全策略,以声明此证据可以授予特定权限。

使用数字证书签署的程序集提供的证据是:此程序集由拥有与此证书关联的私钥的人签名,而且此外,证书持有者的身份已经由VeriSign验证。

数字证书使您的软件用户能够根据您的身份由受信任的第三方验证做出信任决定。

  

那么如何保护我的DLL呢?

它没有。你的DLL是撬棍,它将被用来装饰窗户,而不是一堆金币!您的DLL首先不是要保护的资源。用户的数据是要保护的资源。数字签名有助于促进现有的信任关系。您的客户信任您编写符合标签上所述内容的代码。签名使他们知道他们运行的代码确实来自你,因为代码作者的身份是由受信任的第三方验证的。

  

当然没有强大的命名相同的东西吗?

没有

强命名是类似的,因为强名称DLL向运行时提供加密强有力的证据,表明程序集是由与特定公钥关联的特定私钥签名的。但强命名的目的是不同的。正如该术语所暗示的那样,强命名是关于为只能与实际程序集关联的程序集创建名称。任何人都可以创建一个名为foo.dll的DLL,如果你通过它的弱名称将foo.dll加载到内存中,你将获得该名称的机器上的任何DLL,无论是谁创建它。但只有与公钥对应的私钥的所有者才能使用强名foo, Version=1.2.3.4, Culture=en, PublicKeyToken=03689116d3a4ae33创建一个dll。

同样,强命名的目的不是直接,以促进软件提供商和用户之间的信任关系。强命名的目的是确保使用您的库的开发人员真正使用实际发布的特定版本

  

我注意到VeriSign并不是强命名的一个因素。没有值得信赖的第三方吗?

那是对的;具有强名称的,没有可信第三方验证与给定强名称关联的公钥实际上与特定组织或个人相关联。

数字证书中的这种机制有助于建立信任关系,因为受信任的第三方可以保证公钥确实与受信任的组织相关联。缺乏这种机制,某个强名称的消费者需要知道您组织的公钥是什么。您如何安全地与他们沟通取决于您自己。

  

在强命名的情况下,是否存在其他可能影响第三方的事实?

是。例如,假设有人闯入您的办公室,并使用数字证书私钥窃取计算机。该攻击者现在可以生成使用该密钥签名的软件。但VeriSign等认证机构发布了"撤销清单"已知的受损证书。如果您的客户是最新的从他们的认证机构下载撤销列表,那么一旦您撤销您的证书,他们可以检测到您的软件可能来自敌对的第三方。然后,您需要获得新证书,重新签署所有代码并将其分发给客户,但至少有一些机制可以处理这种情况。

强名称并非如此。没有中央认证机构可以申请受损的强名单。如果你的强名私钥被盗,你就不走运了。没有撤销机制。

  

我查看了我的默认安全策略,它说(1)本地计算机上的任何代码都是完全受信任的,(2)本地计算机上任何由Microsoft强名称的代码都是完全可信的。这不是多余的吗?

是。这样,如果第一个策略更具限制性,那么第二个策略仍然适用。管理员可能希望在不降低必须完全信任的程序集的信任级别的情况下降低已安装软件的信任级别,因为它们会使安全系统保持正常工作,这似乎是合理的。

  

但是等一下,这似乎仍然是多余的。为什么不将默认策略设置为"(1)本地计算机上的任何代码都是可信任的(2)Microsoft强有力的任何代码都是完全可信的"?

假设灾难发生并且Microsoft私钥被泄露。它存放在建筑物11下的拱顶深处,由鲨鱼用激光束保护,但是,假设发生了这种情况。这将是一场史无前例的灾难,因为正如我刚才所说,没有撤销制度。如果发生这种情况并且安全策略如您所述,那么拥有该密钥的攻击者可以将恶意软件置于Internet ,然后由默认安全策略完全信任!实际上已经说明了安全策略 - 需要强名称和本地机器位置 - 拥有私钥的攻击者现在必须欺骗用户下载和安装它。

这是"深度防御"的一个例子。始终假设所有其他安全系统都已失败,并且仍然尽力阻止攻击者。

作为最佳做法,您应始终设置强名称或数字签名政策以包含位置。

  

同样,强有力的命名并不能保护我的DLL。

右。安全系统的目的永远不会保护,软件供应商或您生成的任何工件。它旨在保护您的客户免受那些试图利用客户与您之间信任关系的攻击者的攻击。强名称可确保使用您的库的代码真正使用您的库。它通过为识别特定DLL的特定版本创建一个非常方便的机制来实现这一点。

  

我在哪里可以阅读更多内容?

我已经写过an entire short book on the .NET 1.0 security system但它已经绝版了,并且无论如何都会被新的简化系统所取代。

以下是我就此主题撰写的更多文章:

http://blogs.msdn.com/b/ericlippert/archive/2009/09/03/what-s-the-difference-part-five-certificate-signing-vs-strong-naming.aspx

http://ericlippert.com/2009/06/04/alas-smith-and-jones/


(*)安全系统的目标不是防止攻击成功;良好的安全系统还将提供成功攻击的不可否认证据,以便在攻击后追踪并起诉攻击者。这些功能超出了本讨论的范围。

答案 1 :(得分:5)

简而言之,其中一个主要目的是防止CLR在更改后加载程序集。例如,您运送带有DLL的软件,有人可以反映它,更改代码并再次构建它,并让您的程序加载它认为它是您的DLL。为了防止这种情况,在构建dll并使用它存储时会计算哈希值。在运行时,当CLR加载DLL时,它再次计算哈希并与DLL存储的内容进行比较,如果DLL仍然完好无损,那么它应该匹配,CLR会加载它,否则它将无法加载。

这应该给你一个非常好的解释和更多细节:

http://resources.infosecinstitute.com/dot-net-assemblies-and-strong-name-signature/