什么是公钥令牌?它是如何用汇编强名称计算的?

什么是“公钥令牌”,它是如何用汇编强名来计算的?

关于你的问题,“如何计算”,这是一个SHA1哈希。

来自dot net博客 :

Microsoft通过使用强名称程序集的公钥的哈希来解决“公钥膨胀”问题。 这些哈希称为公钥标记,是强名称程序集公钥的SHA1哈希的低8字节。 SHA1哈希值是160位(20字节)哈希值,并且在此算法中简单地丢弃哈希值的前12个字节。

您可以通过键入以下命令从VS命令行获取PublicKeyToken:

sn –T DLLName.dll 

如果需要基于完整的公钥生成公钥令牌,则此小静态方法可以:

  private static byte[] GetKeyTokenFromFullKey(byte[] fullKey) { SHA1CryptoServiceProvider csp = new SHA1CryptoServiceProvider(); byte[] hash = csp.ComputeHash(fullKey); byte[] token = new byte[8]; for (int i = 0; i < 8; i++ ) token[i] = hash[hash.Length - (i+1)]; return token; } 

来自ECMA-335:

此声明用于在程序集引用中存储发起方公钥的SHA-1哈希的低8字节,而不是完整的公钥。
程序集引用可以存储完整的公钥或8字节的“公钥令牌”。可以使用它们来validation在编译时用于对程序集进行签名的同一私钥也对运行时使用的程序集进行了签名。 两者都不需要存在,虽然两者都可以存储,但这没有用。

[基本原理:存储在程序集引用中的公钥或公钥令牌用于确保被引用的程序集和在运行时实际使用的程序集由拥有相同私钥的实体生成,因此可以假设为一直是出于同一目的。 虽然完整的公钥在加密方面更安全,但它在引用中需要更多存储空间。 公钥令牌的使用减少了存储引用所需的空间,同时仅略微削弱了validation过程。 最终理由]

至于如何计算哈希值(我假设这可能是你要求的,因为公钥令牌没有“计算”),来自同一规范:

CLI元数据允许程序集的生产者计算该程序集的加密哈希值(使用SHA-1哈希函数),然后使用RSA算法(请参阅分区I)和生成器的公钥/私钥对加密它。选择。 然后,可以将结果(“SHA-1 / RSA数字签名”)与RSA算法所需的密钥对的公共部分一起存储在元数据(第25.3.3节)中。 .publickey指令用于指定用于计算签名的公钥。 为了计算散列,将签名归零,计算散列,然后将结果存储到签名中。

强名称(SN)签名过程使用标准散列和密码算法进行强名称签名。 生成大多数PE文件的SHA-1哈希。 该哈希值使用SN私钥进行RSA签名。 出于validation目的,公钥存储在PE文件中以及签名的哈希值中。
除以下内容外,PE文件的所有部分都经过哈希处理:•Authenticode签名条目:PE文件可以进行authenticode签名。 authenticode签名包含在PE头数据目录的偏移128处的8字节条目(第25.2.3.3节中的“证书表”)和该目录条目指定的范围内的PE文件的内容中。 [注意:在符合条件的PE文件中,此条目应为零。 结束注释]•强名称Blob:CLI头的偏移32处的8字节条目(第25.3.3节中的“StrongNameSignature”)以及PE文件中此RVA中包含的哈希数据的内容。 如果8字节条目为0,则没有关联的强名称签名。 •PE标头校验和:PE标头Windows NT特定字段的偏移64处的4字节条目(第25.2.3.2节中的“文件校验和”)。 [注意:在符合条件的PE文件中,此条目应为零。 结束说明]

您可以在这里免费下载规范: http : //www.ecma-international.org/publications/standards/Ecma-335.htm

公钥标记用于标识强名称程序集中的组织。 此信息将添加到程序集元数据库中。 我认为理查德对其存储的技术方式是正确的。

如果要查看程序集的元数据库,请使用ILDASM。 除了查看IL之外,您还可以深入了解元数据库中存储的内容。

它是用于对程序集进行签名的密钥的哈希字节。

因此,不是列出密钥的数百个hex数字,而是更简单,但仍然几乎没有冲突的风险。