.NET程序集不签名有什么问题吗?

96

我的一位同事非常热衷于签署程序集。他几乎会尝试为任何东西签名,即使我们使用的是未签名的 Microsoft 程序集,他也会获取源代码进行签名,然后要求其他开发人员使用他的副本。

我可以理解签署程序集背后的基本想法:确保某个程序集不会被某些可疑黑客入侵。因此,如果我们是一个软件开发公司,我们应该在向客户发布 .NET 库之前对程序集进行签名。

然而,在这里,我们主要开发自己使用的 Web 应用程序,我就是看不出每个使用的程序集都签名的意义所在。

我错过了什么吗?


1
值得注意的是,这里存在一些混淆,“数字签名”(具有安全目的)和“强名称程序集”是解决dll地狱问题并帮助GAC链接到库的修复方法。使用其中之一类似,两者都可以用签署程序集的术语来描述。看起来有些发帖者在考虑一个,而其他人则在考虑另一个或两个都在考虑。 - amalgamate
10个回答

62

我之前曾经利用未签名的程序集来解决问题,并在学术场合向人们展示其重要性。我替换了一个未签名的DLL文件(同样是在学术场合),使用.NET Reflector复制并粘贴原始代码,但我的代码中添加了在调用“真实”代码之前传递的用户名和密码。

如果进行了签名,你可以让签名匹配,但不能进行替换。与Zippy所说的相反,在运行时会出现编译错误。

对程序集进行签名从不会过度。只需要30秒钟的时间就能完成签名。这就像说如果你住在乡村,锁门就太多余了一样。如果您想赌博而不保护您的财物,请随意将其开放。只需要发生一次安全漏洞就可能失去工作。程序集签名只需要30秒钟,没有任何理由不这样做。其性能影响可以忽略不计。


11
如果黑客能够更改dll文件,他也可以更改调用该dll文件的应用程序。 - ZippyV
13
没错,Zippy。但是如果没有签名应用程序所需的密钥,那么他们很难在只允许运行原始应用程序的已签名版本的环境中运行该应用程序,在我工作的几个环境中就是这种情况。你太注重细节了:不签署程序集会带来不必要的安全风险,只需要花费30秒钟即可避免,我从未见过任何业务案例或实际情况不签署程序集的情况。 - user289100

50

在可信环境中使用签名程序集听起来对我来说有点过度了。

关于已签名程序集的一个有趣观点是它们加载速度比未签名程序集稍慢,因为它们必须进行加密验证。

为了签名程序集,任何它依赖的程序集也必须被签名。我猜这会导致您的同事希望对所有东西都进行签名 -- 编译器要求这样做。


编辑 自写本答案以来,可以看到支持签名和反对签名的阵营大致相等。这里显然没有正确的答案。

引起这次编辑的原因是现在我们从NuGet获取了很多开源库,其中许多根本没有签名。如果您想签名您的程序集,则需要将其依赖项也签名。许多已签名的开源库的用于签名的私钥在其源代码存储库中公开可用。

与任何事物一样,需要权衡利���。在我在私人环境中工作的经验中,签名的好处大多是理论上的(或者像@user289100所提到的那样学术性的),除非您担心政府机构修改您的代码,在这种情况下,您需要对您基础架构的许多层进行偏执狂般的关注,签名似乎只是少量的努力。否则,由于必须对所有内容进行签名而产生的挑战似乎并不值得。但您的环境可能有不同的要求,或者您可能是个受虐狂!

还可以参见Teun D's的答案,了解使用强名称时与程序集版本控制相关的挑战信息。


17
同意,对他来说现在就像上瘾一样。 - Janie
3
还有一点需要注意的是,如果您想在不同的应用程序之间共享此程序集,则必须进行签名(即GAC)。 - rajesh pillai

40

另外需要注意的是:对程序集进行签名会破坏向后兼容性。您的引用都会包括版本号,与其他版本号不同的版本会被视为不兼容。这会阻碍升级到较新版本的分布式程序集。

在我看来,只有在以下情况下才应该对程序集进行代码签名:

  • 如果您部署到可能被不受信任的人接触的环境中
  • 在某些插件模型中,您想要将证书用作升级信任的证据
  • 如果您的代码应该能够从其他已签名的代码中调用(例如像log4net这样的项目合理地对其代码进行签名以实现广泛使用;但他们几年前遗失了秘钥,签名的风险也存在兼容性问题)
  • 如果您想要部署到全局程序集缓存(GAC)

9
你的同事是否给出了签名程序集的原因?签名的一个优点是只有签名的程序集才能放置在GAC中(即可以在管理进程之间共享),但从我的(尽管经验不足)角度来看,劣势似乎超过优势。
你关于自签名Microsoft代码的轶事似乎特别可疑。如果MS没有签署该代码,那么很可能有原因,对吧?通过签名它,你要为你没有编写的代码负责,这是未来会伤害你的另一个机会。

2
实际上我不确定为什么,但微软肯定没有签署Enterprise Library 3.1。 - oscarkuo
1
为什么在进程之间共享程序集需要将程序集放置在全局程序集缓存中(GAC)? - Dirk Vollmar
4
不是说你不能在运行时共享对同一.dll的引用,而是只有具有强名称(即已签名的程序集)的程序集才能进入全局程序集缓存(GAC),而程序集会被放入GAC以便共享。 - Dan Davies Brackett

4

关于程序集签名的另一个重要作用是,防止其他人意外或恶意地替换您的程序集。例如,如果您创建了一个引用版本号为1.0的Foo.dll程序集的程序,其他人可能会创建一个同样版本号的程序集并将其替换掉您的程序集。但是,当您对库进行签名后,这种替换就不再容易实现。


4

只有当程序集被放置在全局程序集缓存(GAC)中时,签名才是必要的,其他情况下则不需要。 签名并不能防止别人篡改程序集。黑客仍然可以剥离签名和任何检查签名的代码。


2
对于一个 Web 应用程序,黑客还必须修改 web.config 文件。 - Tangurena
3
如果黑客可以从程序集中删除数字签名,那么 web.config 也无法阻止他们。 - ZippyV
4
建议给负评者阅读http://ianpicknell.blogspot.com/2010/02/tampering-with-strong-named-assembly.html以及从该文章链接的类似文章。 - Constantin
1
当前:是和否。我尝试过,Windows默认情况下不检查签名(“强名称”)。可能是为了用户友好:-) 引用的链接显示了添加到App.config以强制执行签名检查的内容。然后,与文章相反,签名检查确实起作用并检测任何篡改,无论是版本号还是内容。 - Roland

3

我认为这似乎有点浪费。但实际上,签名是确保文件是你所想的(并且没有被篡改)所必需的。但是,如果你信任自己网络安全和Web服务器的限制,那么对你的Web程序集进行签名似乎是一步多余的。

但也许这是我小企业经验在说话。如果你谈论的是关键任务的在线银行网站,那么请毫不犹豫地进行签名。


2

如果你要发货或者确实有理由这样做,那就考虑去做吧。在其他情况下,这只是麻烦。我建议询问你的同事,他真正从中获得了什么。

我之前遇到过签名程序集问题,它很让人头疼,特别是考虑到有很多人对签名程序集一无所知,不知道它的作用以及如何操作。这只是另一件除非绝对必要否则你不应该自己去关心的事情。


1
我们对程序集进行签名是因为有时会出现以下错误(这个例子是来自测试,但在运行应用程序时也可能发生):
System.IO.FileLoadException : Could not load file or assembly 'Latitude.Platform.Core, Version=1.0.5871.22518, Culture=neutral, PublicKeyToken=7926214d13e12325' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

TearDown : System.IO.FileLoadException : Could not load file or assembly 'Latitude.Platform.Core, Version=1.0.5871.22518, Culture=neutral, PublicKeyToken=7926214d13e12325' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

我们发现有时候Visual Studio会出错,运行旧代码。
如果你想在运行旧代码时出现错误,请对程序集进行签名。
如果你正在编写一个nuget包,请签署你的程序集。未签名的程序集对于我们想确保运行最新版本代码的人来说很麻烦。我无法修复Visual Studio。我所能做的只是检测到Visual Studio出错了。因此,请签署你的nuget程序集

更新:使用未签名程序集的潮流正在获胜 ;) 我们正在以不同的方式解决上述问题:从空目录或“清理”目录开始在CI服务器上构建和测试。也许我们在开发机器上本地拥有这种情况,但它很少发生或没有太大的实际影响。 - Clay Lenhart

1

当程序集在通过Web部署ClickOnce XBAP时使用时,您需要对其进行签名。

此外,所有引用的程序集也需要进行签名。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接