【发布时间】:2009-02-21 14:09:32
【问题描述】:
什么是“公钥令牌”,它是如何在程序集强名称中计算的?
【问题讨论】:
-
公钥是与私钥相对应的密钥(又用于签署程序集)。看看Strong-Named Assemblies
标签: c# publickeytoken
什么是“公钥令牌”,它是如何在程序集强名称中计算的?
【问题讨论】:
标签: c# publickeytoken
关于您的问题,“它是如何计算的”,它是一个 SHA1 哈希。
来自dot net blog:
微软解决“公钥 膨胀”问题通过使用 强命名程序集的公钥。 这些哈希被称为公共 密钥令牌,并且是低 8 字节 强命名的 SHA1 哈希 程序集的公钥。 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 字节的“公钥令牌”。两者都可以用来 验证用于在编译时对程序集进行签名的同一私钥是否也对在编译时使用的程序集进行了签名 运行。两者都不需要存在,虽然两者都可以存储,但这没有用。[基本原理:存储在程序集引用中的公钥或公钥令牌用于确保 被引用的程序集和在运行时实际使用的程序集是由拥有的实体产生的 具有相同的私钥,因此可以假定其目的是相同的。虽然 完整的公钥在密码学上更安全,它需要更多的参考存储空间。公钥的使用 token 减少了存储引用所需的空间,同时略微削弱了验证过程。 结束理由]
至于如何计算哈希(我假设这可能是您要问的,因为公钥令牌不是“计算”的),来自相同的规范:
CLI 元数据允许程序集的生产者计算该程序集的加密哈希(使用 SHA-1 散列函数),然后使用 RSA 算法(参见分区 I)和公共/私有 生产者选择的密钥对。然后可以存储此结果(“SHA-1/RSA 数字签名”) 元数据(第 25.3.3 节)以及 RSA 算法所需的密钥对的公共部分。这 .publickey 指令用于指定用于计算签名的公钥。计算 哈希,签名归零,计算哈希,然后将结果存储到签名中。
强名称 (SN) 签名过程使用标准哈希和密码算法进行强名称签名。一个 生成大部分 PE 文件的 SHA-1 哈希。该哈希值是使用 SN 私钥进行 RSA 签名的。为了 验证目的,公钥与签名的哈希值一样存储在 PE 文件中。
除以下内容外,PE 文件的所有部分都经过哈希处理: • 验证码签名条目:PE 文件可以进行验证码签名。验证码 签名包含在 PE 头数据目录偏移 128 处的 8 字节条目中 (第 25.2.3.3 节中的“证书表”)和此指定范围内的 PE 文件的内容 目录条目。 [注意:在符合标准的 PE 文件中,该条目应为零。尾注] • 强名称 Blob:CLI 标头偏移 32 处的 8 字节条目(“StrongNameSignature” 在第 25.3.3 节中)以及 PE 文件中此 RVA 中包含的哈希数据的内容。如果 8 字节 条目为 0,没有关联的强名称签名。 • PE 标头校验和:PE 标头偏移 64 处的 4 字节条目 Windows NT-Specific 字段(第 25.2.3.2 节中的“文件校验和”)。 [注意:在符合标准的 PE 文件中,该条目应为零。 尾注]
您可以在此处免费下载规范:http://www.ecma-international.org/publications/standards/Ecma-335.htm
【讨论】:
公钥令牌用于标识强命名程序集中的组织。此信息将添加到程序集元数据库中。我会假设 Richard 关于存储它的技术方式是正确的。
如果要查看程序集的元数据库,请使用 ILDASM。除了查看 IL 之外,您还可以深入了解元数据库中存储的内容。
【讨论】:
它是用于对程序集进行签名的密钥的哈希字节。
因此,与其列出密钥的数百个十六进制数字,您还有一些更简单的东西,但碰撞风险仍然很小。
【讨论】: