公钥令牌的作用是什么?
公钥令牌是一个小数字,它是代表公钥的便捷“令牌”。公钥非常长;公钥令牌的目的是让您可以引用密钥而不必说出整个密钥。有点像说“指环王”这五个单词代表了一个50万字的小说。如果每次想要谈论它,都必须说出那50万个单词,那将会相当不方便。
公钥令牌在解密签名哈希中起到了什么作用吗?
没有。公钥令牌中没有任何“信息”。它只是一个数字,代表一个公钥。它本身不是公钥。
为什么微软的许多程序集具有相同的公钥令牌?
因为它们都使用了相同的私钥——微软的私钥——因此都是用相同的公钥进行验证,因此都具有相同的公钥令牌。
来自维基百科
"公钥标记用于使程序集名称独特。因此,两个强命名的程序集可以具有相同的PE文件名称,但.NET将识别它们为不同的程序集。Windows文件系统(FAT32和NTFS)仅识别PE文件名称,因此具有相同PE文件名称(但不同文化、版本或公钥标记)的两个程序集不能存在于同一Windows文件夹中。为解决这个问题,.NET引入了一个称为GAC(全局程序集缓存)的东西,它被.NET CLR视为单个文件夹,但实际上是使用嵌套的NTFS(或FAT32)文件夹实现的。
为了防止欺骗攻击,其中黑客会尝试将装配体作为其他内容传递,该装配体使用私钥签名。拟定装配体的开发人员保持私钥机密,因此黑客无法访问它也无法猜测它。因此,黑客无法将其装配体伪装成其他物品,也无法在更改后正确签署它。签署程序集涉及对程序集的重要部分进行哈希,并使用私钥加密哈希。已签名的哈希与公钥一起存储在程序集中。 公钥将解密已签名的哈希。当CLR加载强命名的程序集时,它将从程序集生成哈希,然后将其与解密的哈希进行比较。如果比较成功,则意味着文件中的公钥(因此也是公钥标记)与用于签署程序集的私钥相关联。这意味着程序集中的公钥是程序集发布者的公钥,因此可以防止欺骗攻击。
哈希值有点像“指纹”。它使用签名者拥有(并且仅知道)的私钥进行签名。如果您知道签名者的公钥,您可以检查哈希值是否真的来自签名者,因此数据/文件是否真的来自签名者(并且未更改)。在GAC中对于某些文件相同的公钥意味着“所有文件都由同一签名者签名”。
我想在之前的回答中补充一些内容(特别是引用自维基百科的那个回答),即通过公钥/私钥进行强命名并不能保护您免受被更改的程序集或防止有人篡改您的程序集。
首先,强名称并不能保证程序集是可信的。您只有公钥/公钥令牌,但不知道签名者是谁(除非他们以某种方式宣布拥有程序集的公钥)。
例如,黑客可以获取您的程序集,从中删除强名称(有工具可以实现此操作),再用自己的强名称对其进行签名。 对于信任,有一种不同类型的数字代码签名与证书有关。它涉及第三方检查您和您的公司,并且不是免费的。请查看 Authenticode 技术:
https://msdn.microsoft.com/en-us/library/ms537359(v=vs.85).aspx
其次,接下来的讨论中简要描述了一种暴力攻击方法,用于获取具有相同公钥令牌的公钥/私钥对,该方法会为篡改的程序集生成相同的哈希值。https://groups.google.com/forum/?hl=en#!topic/microsoft.public.dotnet.security/Jo6PqypxJN8
我必须指出,这个问题可以通过增强的强名称https://learn.microsoft.com/en-us/dotnet/framework/app-domains/enhanced-strong-naming来解决。http://www.grimes.nildram.co.uk/workshops/fusionWSCrackThree.htm
第三,启动.Net 3.5 sp1以提高装配件的负载性能,默认情况下不验证完全信任的装配件。
装配的条件: https://blogs.msdn.microsoft.com/shawnfa/2008/05/14/strong-name-bypass/ 关于此问题在Stack Overflow上的讨论: Are signed .net assemblies ever fully verified when loaded, to check they haven't been modified? 据我了解,这意味着装配在加载时未进行哈希处理以检查其是否已被篡改。附言:对于带有许多参考资料的长篇文章,我感到非常抱歉。