.net 公钥令牌的作用是什么?

4dc9hkyq  于 2023-10-21  发布在  .NET
关注(0)|答案(5)|浏览(161)

公钥令牌的作用是什么?它有没有参与解密签名的散列。在GAC中,为什么有这么多来自Microsoft的程序集具有相同的公钥标记?

r1wp621o

r1wp621o1#

公钥令牌的作用是什么?
公钥令牌是一个很小的数字,它是一个方便的“令牌”,代表一个公钥。公钥很长;公钥令牌的目的是让您引用密钥,而不用说出整个密钥。就像说“指环王”是五个词,代表了一部50万字的小说。如果每次你想谈的时候,你都要说出那五十万字,那就太不方便了。
它有没有参与解密签名的散列?
公钥令牌中没有“信息”。它只是一个数字,代表一个公钥。它本身不是公钥。
为什么有这么多来自Microsoft的程序集具有相同的公钥标记?
因为它们都是用相同的私钥(Microsoft的私钥)签名的,因此都是用相同的公钥验证的,因此都具有相同的公钥令牌。

v09wglhw

v09wglhw2#

Wikipedia
“公钥标记用于使程序集名称唯一。因此,两个强命名程序集可以具有相同的PE文件名,但.NET会将它们识别为不同的程序集。Windows文件系统(FAT32和NTFS)只识别PE文件名,因此同一个Windows文件夹中不能存在两个具有相同PE文件名(但区域性、版本或公钥标记不同)的程序集。为了解决这个问题,.NET引入了一种称为GAC(全局程序集缓存)的东西,它被.NET缓存视为单个文件夹,但实际上是使用嵌套的NTFS(或FAT 32)文件夹实现的。
为了防止欺骗攻击,即黑客试图将程序集伪装成其他东西,程序集使用私钥签名。预期程序集的开发人员将私钥保密,因此黑客无法访问它,也无法简单地猜测它。因此,破解者不能让他的程序集模拟其他东西,在更改后缺乏正确签名的可能性。对程序集进行签名涉及获取程序集重要部分的哈希,然后使用私钥对哈希进行加密。签名的哈希值与公钥一起沿着存储在程序集中。**公钥将解密签名的哈希。**当MySQL加载强名称程序集时,它将从程序集生成哈希,然后将其与解密的哈希进行比较。如果比较成功,则意味着文件中的公钥(以及公钥标记)与用于对程序集进行签名的私钥相关联。这意味着程序集中的公钥是程序集发行者的公钥,因此可以阻止欺骗攻击。”

pjngdqdw

pjngdqdw3#

哈希是一种“指纹”。它使用签名者拥有(并且仅知道)的私钥进行签名。如果你知道签名者的公钥,你可以检查哈希是否真的来自签名者,因此数据/文件是否真的来自签名者(并且没有改变)。GAC中某些文件的相同公钥意味着“所有文件都由同一个签名者签名”。

0md85ypi

0md85ypi4#

公钥令牌是真实的公钥的可读摘录。完整的公钥存储在签名的程序集中,用于解密签名(=加密的哈希)。加载程序使用它来验证内容没有被篡改(或损坏)。原始散列由作者使用私钥加密,只有拥有该密钥的人才能产生有效的签名。
每个公司(或部门)应该只使用1个密钥对,这就是为什么你在GAC中看到相同的PKT组。

q8l4jmvw

q8l4jmvw5#

我想补充一下前面的答案(特别是引用Wikipedia的那个),通过公钥/私钥的强命名并不能保护你不被更改程序集,也不能防止有人篡改你的程序集。

首先,强名称不能保证程序集可信。你只有一个公钥/公钥令牌,但你不知道谁签署了它(除非他们以某种方式宣布他们拥有程序集公钥)。

例如,黑客可以获取您的程序集,从其中删除强名称(有工具可以做到这一点),并使用自己的强名称对其进行签名。对于信任,有一种不同类型的数字代码签名与证书。它涉及第三方检查您和您的公司,并不是免费的。查看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来解决
在讨论中还提到了一个bug,它允许跳过程序集的验证,并在运行时加载一个被篡改的程序集。详细的研究在这里,这个bug在.Net framework的后续版本中得到了修复(所以这个bug出现在旧的.Net 1中):
http://www.grimes.nildram.co.uk/workshops/fusionWSCrackThree.htm

第三,启动.Net 3.5 sp1以提高程序集加载的性能默认情况下不验证完全信任程序集。

https://learn.microsoft.com/en-us/dotnet/framework/app-domains/how-to-disable-the-strong-name-bypass-feature
程序集的条件: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?
据我所知,这意味着在加载过程中不会对汇编进行散列,以检查它是否

最后,我想提一下,关于强命名的利弊有一个争论,因为它们要求你指定一个程序集版本。Microsoft从某些产品中删除了强名称:https://www.pedrolamas.com/2016/03/01/still-strong-naming-your-assemblies-you-do-know-its-2016-right/

    • 当我遇到强命名时,我被MSDN和Wikipedia误导了,以为它可以为程序集提供某种防御。我想“酷”和强烈的命名留在我的记忆中作为一种保护机制。直到那一刻,我不得不考虑我的snk文件与私钥的安全性,然后我的同事告诉我,这不是那么“酷”.所以我做了点调查。我学到的第一件事是,强名称并不意味着信任,您应该使用证书。尽管如此,我认为如果我保持我的私钥安全,那么被篡改的程序集就不会被我签名,这意味着如果有人要修改我的程序集,那么他也必须修改签名,修改后的程序集就不会被安装程序加载。现在我不认为强有力的命名保证了这一点。因此,您应该只依赖它来保证程序集的唯一性。

PS.对不起,这篇文章很长,有很多参考资料。

相关问题