29

My application consists of three assemblies: a single EXE which references a couple of DLLs. The DLLs are private to my application - they are used only by this executable.

Should these assemblies be given a strong name?

FxCop suggests that they should - for all of the assemblies it currently produces:

CA2210: Sign <assembly> with a strong name key.

However, this advice says:

In general, you should avoid strong-naming application EXE assemblies.

and

you may want to avoid strong-naming components that are private to your application.

Should I give these assemblies a strong name? What are the benefits of doing so (or not doing so) in this case?

Edit:

Looking at several applications with a similar structure, there seems to be no consensus on this issue. The binaries of Paint.NET and Crack.NET are not strong-named, whereas those of .NET Reflector and Snoop are.

Interestingly, with the Expression suite Microsoft have taken the latter approach: in Expression Blend, for example, they have chosen to strong-name sign both Blend.exe and the accompanying DLLs (such as Microsoft.Expression.Blend.dll).

It seems that I am unlikely to receive a simple answer to my first question: "Should I give these assemblies a strong name?". However, my second question still stands:

Are there any benefits to strong-name signing binaries in this situation? Or, are there any benefits to not doing so?

Edit 2:

If there are no overwhelming reasons to go either way, I am inclined towards giving my assemblies a strong name. I'd thus be interested in whether anyone can expand upon this (from the first link):

"strong-naming can make it more difficult to manage dependencies and add unnecessary overhead for private components."

4

4 回答 4

16

在我看来,这些是在这种情况下强名称签名的好处:

  • 防止攻击者将 DLL 替换为使用另一个密钥签名(或根本没有签名)的 DLL,而不替换 EXE(因为 EXE 包含包含公钥的引用)。
  • 防止攻击者在保留现有密钥的同时修改程序集(因为这将导致签名验证失败)。但是请注意,从 .NET 3.5 SP1 开始,默认情况下禁用这种情况下的签名验证。
  • 可以防止应用程序使用不匹配的程序集版本运行 - 如果由于部署错误而错误地替换了 DLL,则应用程序将无法加载它,而不是尝试使用(可能不兼容的)错误版本。
  • 避免 FxCop 警告。

以及签名的缺点(我相信这些是链接文章所指的):

  • 用兼容的较新版本替换 DLL(例如,为了修复错误)需要替换 EXE。
  • 在 .NET 版本 < 3.5 SP1 中,由于签名验证,强名称程序集的加载时间更长。
  • 强命名的 DLL 也需要更长的时间来加载,因为加载器在本地查找之前会执行(在这种情况下是徒劳的)GAC 搜索。

选择是强命名(因此需要引用以匹配确切的键和确切的版本)或不是强命名(并且不需要两者都匹配)似乎很可惜。如果可能需要密钥而不是特定版本,那么也许可以获得签名的前两个好处,而不会同时获得第一个缺点。也许这可以通过应用一个强名称然后使用 app.config 处理版本控制问题来实现?

于 2010-02-17T02:44:55.877 回答
5

强命名程序集仅确保版本兼容性。这与信任程序集不同。

换句话说,“强名称”仅指与编译时使用的版本号相结合的确切程序集二进制文件。

如果您对这些程序集进行 GAC,则 CLR 只会对其进行一次验证。当时大会是gac'd。这可以导致性能改进。但是,我的经验表明它是最小的。

强命名程序集可以替换为非强命名程序集;这提出了关于强命名不是任何类型的安全功能的部分。

我个人的观点是,与它们相关的疼痛程度并不能证明使用它们是合理的。痛苦在于他们如何使用自动化测试工具。

https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5054496.html

于 2010-02-17T00:26:02.783 回答
4

对程序集签名可确保程序集在编译后不被修改。只要您是唯一的私钥所有者,就没有人能够使用您的密钥对程序集进行签名。

当然,这不是绝对的保护。黑客可以修改程序集并从所有程序集中删除强名称签名(和引用)。这些组件也可以工作。

但在这种情况下,您可以说这些修改不是由您进行的。

于 2010-02-16T08:34:03.747 回答
1

如果您对程序集进行签名,则任何引用的程序集都会公开公开,它们也必须进行签名。否则,您将有充分的理由得到一个编译错误。

我认为强命名程序集的主要用途是将其纳入 GAC。

我认为不需要强命名 exe。

只是我的 2 比索....

于 2010-02-15T20:57:38.330 回答