什么是“公钥令牌”,它是如何在程序集强名称中计算的?
6 回答
关于您的问题,“它是如何计算的”,它是一个 SHA1 哈希。
来自点网博客:
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 字节的“公钥令牌”。两者都可用于验证用于在编译时对程序集进行签名的同一私钥是否也对在运行时使用的程序集进行了签名。两者都不需要存在,虽然两者都可以存储,但这没有用。[基本原理:存储在程序集引用中的公钥或公钥令牌用于确保被引用的程序集和运行时实际使用的程序集是由拥有相同私钥的实体生成的,因此可以假设旨在用于相同目的。虽然完整的公钥在密码学上更安全,但它需要更多的参考存储空间。公钥令牌的使用减少了存储引用所需的空间,同时仅略微削弱了验证过程。结束理由]
至于如何计算散列(我假设这可能是您要问的,因为公钥令牌不是“计算”的),来自相同的规范:
CLI 元数据允许程序集的生产者计算该程序集的加密哈希(使用 SHA-1 哈希函数),然后使用 RSA 算法(参见第 I 部分)和生产者的公钥/私钥对对其进行加密。选择。然后可以将其结果(“SHA-1/RSA 数字签名”)与 RSA 算法所需的密钥对的公共部分一起存储在元数据(第 25.3.3 节)中。.publickey 指令用于指定用于计算签名的公钥。为了计算哈希,签名归零,计算哈希,然后将结果存储到签名中。
强名称 (SN) 签名过程使用标准哈希和密码算法进行强名称签名。生成大部分 PE 文件的 SHA-1 散列。该哈希值是使用 SN 私钥进行 RSA 签名的。出于验证目的,公钥与签名的哈希值一样存储在 PE 文件中。
除以下内容外,PE 文件的所有部分都经过哈希处理: • 验证码签名条目:PE 文件可以进行验证码签名。验证码签名包含在 PE 头数据目录(第 25.2.3.3 节中的“证书表”)偏移量 128 处的 8 字节条目中,以及该目录条目指定范围内的 PE 文件的内容。[注意:在符合标准的 PE 文件中,该条目应为零。end note] • 强名称 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 之外,您还可以深入了解元数据库中存储的内容。
它是用于签署程序集的密钥的哈希字节。
因此,与其列出密钥的数百个十六进制数字,您还可以拥有更简单的东西,但碰撞风险仍然很小。