我的一位同事非常热衷于签署程序集。他几乎会尝试为任何东西签名,即使我们使用的是未签名的 Microsoft 程序集,他也会获取源代码进行签名,然后要求其他开发人员使用他的副本。
我可以理解签署程序集背后的基本想法:确保某个程序集不会被某些可疑黑客入侵。因此,如果我们是一个软件开发公司,我们应该在向客户发布 .NET 库之前对程序集进行签名。
然而,在这里,我们主要开发自己使用的 Web 应用程序,我就是看不出每个使用的程序集都签名的意义所在。
我错过了什么吗?
我的一位同事非常热衷于签署程序集。他几乎会尝试为任何东西签名,即使我们使用的是未签名的 Microsoft 程序集,他也会获取源代码进行签名,然后要求其他开发人员使用他的副本。
我可以理解签署程序集背后的基本想法:确保某个程序集不会被某些可疑黑客入侵。因此,如果我们是一个软件开发公司,我们应该在向客户发布 .NET 库之前对程序集进行签名。
然而,在这里,我们主要开发自己使用的 Web 应用程序,我就是看不出每个使用的程序集都签名的意义所在。
我错过了什么吗?
我之前曾经利用未签名的程序集来解决问题,并在学术场合向人们展示其重要性。我替换了一个未签名的DLL文件(同样是在学术场合),使用.NET Reflector复制并粘贴原始代码,但我的代码中添加了在调用“真实”代码之前传递的用户名和密码。
如果进行了签名,你可以让签名匹配,但不能进行替换。与Zippy所说的相反,在运行时会出现编译错误。
对程序集进行签名从不会过度。只需要30秒钟的时间就能完成签名。这就像说如果你住在乡村,锁门就太多余了一样。如果您想赌博而不保护您的财物,请随意将其开放。只需要发生一次安全漏洞就可能失去工作。程序集签名只需要30秒钟,没有任何理由不这样做。其性能影响可以忽略不计。
在可信环境中使用签名程序集听起来对我来说有点过度了。
关于已签名程序集的一个有趣观点是它们加载速度比未签名程序集稍慢,因为它们必须进行加密验证。
为了签名程序集,任何它依赖的程序集也必须被签名。我猜这会导致您的同事希望对所有东西都进行签名 -- 编译器要求这样做。
编辑 自写本答案以来,可以看到支持签名和反对签名的阵营大致相等。这里显然没有正确的答案。
引起这次编辑的原因是现在我们从NuGet获取了很多开源库,其中许多根本没有签名。如果您想签名您的程序集,则需要将其依赖项也签名。许多已签名的开源库的用于签名的私钥在其源代码存储库中公开可用。
与任何事物一样,需要权衡利���。在我在私人环境中工作的经验中,签名的好处大多是理论上的(或者像@user289100所提到的那样学术性的),除非您担心政府机构修改您的代码,在这种情况下,您需要对您基础架构的许多层进行偏执狂般的关注,签名似乎只是少量的努力。否则,由于必须对所有内容进行签名而产生的挑战似乎并不值得。但您的环境可能有不同的要求,或者您可能是个受虐狂!
还可以参见Teun D's的答案,了解使用强名称时与程序集版本控制相关的挑战信息。
另外需要注意的是:对程序集进行签名会破坏向后兼容性。您的引用都会包括版本号,与其他版本号不同的版本会被视为不兼容。这会阻碍升级到较新版本的分布式程序集。
在我看来,只有在以下情况下才应该对程序集进行代码签名:
关于程序集签名的另一个重要作用是,防止其他人意外或恶意地替换您的程序集。例如,如果您创建了一个引用版本号为1.0的Foo.dll程序集的程序,其他人可能会创建一个同样版本号的程序集并将其替换掉您的程序集。但是,当您对库进行签名后,这种替换就不再容易实现。
只有当程序集被放置在全局程序集缓存(GAC)中时,签名才是必要的,其他情况下则不需要。 签名并不能防止别人篡改程序集。黑客仍然可以剥离签名和任何检查签名的代码。
我认为这似乎有点浪费。但实际上,签名是确保文件是你所想的(并且没有被篡改)所必需的。但是,如果你信任自己网络安全和Web服务器的限制,那么对你的Web程序集进行签名似乎是一步多余的。
但也许这是我小企业经验在说话。如果你谈论的是关键任务的在线银行网站,那么请毫不犹豫地进行签名。
如果你要发货或者确实有理由这样做,那就考虑去做吧。在其他情况下,这只是麻烦。我建议询问你的同事,他真正从中获得了什么。
我之前遇到过签名程序集问题,它很让人头疼,特别是考虑到有很多人对签名程序集一无所知,不知道它的作用以及如何操作。这只是另一件除非绝对必要否则你不应该自己去关心的事情。
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)