C# 什么是公钥令牌,它是如何在程序集强名称中计算的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/573079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 08:46:51  来源:igfitidea点击:

What is a public key token and how is it calculated in assembly strong names?

c#publickeytoken

提问by Praveen Sharma

What is a 'public key token' and how is it calculated in assembly strong names?

什么是“公钥令牌”,它是如何在程序集强名称中计算的?

采纳答案by Cerebrus

Regarding your question, "How is it calculated", it's an SHA1 hash.

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

From dot net blog:

来自点网博客

Microsoft solves the "public key bloat" problem by using a hash of the strongly-named assembly's public key. These hashes are referred to as public key tokens, and are the low 8 bytes of the SHA1 hash of the strongly-named assembly's public key. SHA1 hashes are 160 bit (20 byte) hashes, and the top 12 bytes of the hash are simply discarded in this algorithm.

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

回答by Richard

It is the hash bytes of the key used to sign the assembly.

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

So rather than listing out hundreds of hex digits for the key, you have something simpler, but still with little risk of collisions.

因此,与其为密钥列出数百个十六进制数字,您还有一些更简单的方法,但冲突的风险仍然很小。

回答by Gregory A Beamer

A public key token is used to identify the organization in a strongly named assembly. This information is added to the assembly metabase. I would assume Richard is correct about the technical way it is stored.

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

If you want to view the metabase of an assembly, use ILDASM. You can drill down into what is stored in the metabase in addition to seeing the IL.

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

回答by mletterle

From ECMA-335:

来自 ECMA-335:

This declaration is used to store the low 8 bytes of the SHA-1 hash of the originator's public key in the assembly reference, rather than the full public key.
An assembly reference can store either a full public key or an 8-byte “public key token.” Either can be used to validate that the same private key used to sign the assembly at compile time also signed the assembly used at runtime. Neither is required to be present, and while both can be stored, this is not useful.

[Rationale: The public key or public key token stored in an assembly reference is used to ensure that the assembly being referenced and the assembly actually used at runtime were produced by an entity in possession of the same private key, and can therefore be assumed to have been intended for the same purpose. While the full public key is cryptographically safer, it requires more storage in the reference. The use of the public key token reduces the space required to store the reference while only weakening the validation process slightly. end rationale]

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

[理由:存储在程序集引用中的公钥或公钥令牌用于确保被引用的程序集和运行时实际使用的程序集是由拥有相同私钥的实体生成的,因此可以假设为已用于相同目的。虽然完整的公钥在密码学上更安全,但它需要更多的参考存储空间。公钥令牌的使用减少了存储引用所需的空间,同时仅略微削弱了验证过程。结束理由]

As for how the hash is calculated (I assume this may be what you're asking since the public key token is not "calculated"), from the same spec:

至于哈希是如何计算的(我认为这可能是您要问的,因为未“计算”公钥令牌),来自同一规范:

The CLI metadata allows the producer of an assembly to compute a cryptographic hash of that assembly (using the SHA-1 hash function) and then to encrypt it using the RSA algorithm (see Partition I) and a public/private key pair of the producer's choosing. The results of this (an “SHA-1/RSA digital signature”) can then be stored in the metadata (§25.3.3) along with the public part of the key pair required by the RSA algorithm. The .publickey directive is used to specify the public key that was used to compute the signature. To calculate the hash, the signature is zeroed, the hash calculated, and then the result is stored into the signature.

The Strong Name (SN) signing process uses standard hash and cipher algorithms for Strong name signing. An SHA-1 hash over most of the PE file is generated. That hash value is RSA-signed with the SN private key. For verification purposes the public key is stored into the PE file as well as the signed hash value.
Except for the following, all portions of the PE File are hashed: ? The Authenticode Signature entry: PE files can be authenticode signed. The authenticode signature is contained in the 8-byte entry at offset 128 of the PE Header Data Directory (“Certificate Table” in §25.2.3.3) and the contents of the PE File in the range specified by this directory entry. [Note: In a conforming PE File, this entry shall be zero. end note] ? The Strong Name Blob: The 8-byte entry at offset 32 of the CLI Header (“StrongNameSignature” in §25.3.3) and the contents of the hash data contained at this RVA in the PE File. If the 8-byte entry is 0, there is no associated strong name signature. ? The PE Header Checksum: The 4-byte entry at offset 64 of the PE Header Windows NT-Specific Fields (“File Checksum” in §25.2.3.2). [Note: In a conforming PE File, this entry shall be zero. end note]

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

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

You can download the spec here for free: http://www.ecma-international.org/publications/standards/Ecma-335.htm

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

回答by Todd Kobus

If you need to generate a public key token based on a full public key, this little static method works:

如果您需要基于完整的公钥生成公钥令牌,这个小的静态方法可以工作:

   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;
    }

回答by Saurabh Kumar

You can get the PublicKeyToken from the VS Command Line by typing:

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

sn –T DLLName.dll