What is a \'public key token\' and how is it calculated in assembly strong names?
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.
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.
You can get the PublicKeyToken from the VS Command Line by typing:
sn –T DLLName.dll
Regarding your question, "How is it calculated", it's an SHA1 hash.
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.
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;
}
From 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]
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]
You can download the spec here for free: http://www.ecma-international.org/publications/standards/Ecma-335.htm