使用强名称签名如何保护免受一组程序集的伪造?

8

使用强名称进行签名(密钥对存储在.snk文件中)是为了防止伪造程序集等用途。

例如:我使用强名称签名我的程序集,然后其他开发人员使用我的程序集,因此他的程序集现在包含对我的引用,提到我的密钥对的公钥。一些用户安装了该开发人员程序集和我的程序集,并愉快地使用该开发人员的代码。如果其他人试图生成一个看起来像我的版本的程序集,并说服用户它是“值得安装的更新”,那么伪造的程序集将无法加载,因为我控制我的密钥对,而伪造的程序集未使用相同的密钥对进行签名。好吧,很酷。

但是,有什么能够防止恶意方伪造我的程序集和其他开发人员的依赖程序集并“发布”它们两个呢?他们获取我的程序集和该开发人员的程序集,篡改两者,用任何密钥对签署我的程序集的伪造版本,然后将其引用添加到依赖程序集的伪造版本中,也对其进行签名,然后同时发布这两个程序集。我的意思是,恶意地“发布”两个程序集不应该比“发布”一个程序集更难。

强名称签名如何防止伪造多个程序集?


好的,也要对该程序集进行强名称处理。继续拉这根线,你最终会到达EXE文件。如果攻击者也能替换它,那么使用强名称就没有意义了。 - Hans Passant
@Hans Passant:我想你是对的。你能把这个作为答案添加吗? - sharptooth
2个回答

6
强名称程序集的目的并不是为了保护已签名的程序集,而是为了保护加载已签名程序集的其他程序集。
例如,如果一个可信任的exe想要从已知位置(如GAC、网络共享、互联网等)加载已知的DLL,那么使用强名称就可以在某种程度上确保该程序集未被篡改。
但是,如果整套程序集被反汇编、重新组装并重新签名,那么是的,你是正确的,他们可能只需重新编写加载其余程序集的代码行,以使用新的(假)密钥进行加载。
但这种篡改是明显的。换句话说,强名称签名提供了清晰的篡改证据,但并非在所有情况下均可预防。再加上本地管理员可以完全禁用强名称验证(出于“开发”目的),很明显强名称签名不是一种百分之百可靠的安全机制。
同样地,身份验证和驱动程序签名也是如此。我们都见过某些产品指示用户“忽略安全警告”。如果禁用了强名称验证或整个程序集的签名,则该exe基本上也会忽略警告。

2

强名称(Strong Naming)是关于“命名”的全部内容。我从这里引用:使用强名称签名

“强名称为.NET Framework程序集提供了一个强大的机制,使其具有唯一的标识。”

这就是你从这个机制中得到的全部。这意味着我可以伪造你的程序集及其引用的所有程序集,但我将无法假装“你做到了”。我将无法假装是这些程序集的发布者。


我看到的问题是整个基础设施都没有包括公钥发布。假设我下载了一个程序集并想找出它是否来自您。我该怎么办? - sharptooth
@sharptooh - 你可以使用新的ICLRStrongName接口(http://msdn.microsoft.com/en-us/library/dd409349.aspx)来做一些事情,例如StrongNameCompareAssemblies,但是如果你在应用程序中添加这种检查,调用也可能被伪造 :-) - Simon Mourier
是的,确切地说,问题在于没有中央方式可以发布您的公钥。这是因为整个机制不是用于验证组件是否来自您 - 它仅用于验证所有后续版本是否来自与初始版本相同的发布者。 - sharptooth
在.NET 4之前,您可以使用StrongNameMembershipCondition。由于.NET 4改变了所有策略的工作方式,我不确定它是否仍然是一种选择。 - Simon Mourier

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