What’s the Deal with the ECMA Key?

The libraries laid out in the ECMA spec are all signed with a public key that looks pretty strange.  If you ildasm mscorlib.dll, System.dll, or any of the other framework libraries that are defined in the ECMA specs (see partition IV: Library  if you’re interested in which libraries these are), you’ll notice a peculiar looking public key:

.publickey = (00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 )

That looks very strange, and not at all like a strong key.  This key is called the Standard Public Key (sometimes referred to as the ECMA public key), and has a public key token of b77a5c561934e089.  If you have the SSCLI installed,  you’ll see this key defined as the “neutral key” in the file sscli\clr\src\dlls\mscorsn\strongname.cpp. (lines 107 and 109).

By looking at the format of public key blobs, defined in strongname.h (line 38 in sscli\clr\src\inc\strongname.h in the SSCLI, line 28 of <SDK root>\inc\strongname.h in the .NET Framework 1.1 SDK), you’ll see it’s defined as follows:

// Public key blob binary format.
typedef struct {
  unsigned int  SigAlgID;     // (ALG_ID) signature algorithm used to create the signature
  unsigned int  HashAlgID;    // (ALG_ID) hash algorithm used to create the signature
  ULONG        cbPublicKey;  // length of the key in bytes
  BYTE         PublicKey[1]; // variable length byte array containing the key value in format output by CryptoAPI
} PublicKeyBlob;

So, the standard public key actually has 0 for both algorithm IDs, a length of 4 bytes, and all of those bytes are set to 0.  This means that the standard public key is actually a 16 bit key of all zeros.

The mechanism behind this key is actually pretty clever.  Since the ECMA spec lays out the specifications for how any implementation of the CLI should work, it can’t say that everyone must sign with the Microsoft key.  If it did that, then Microsoft would either have to sign anyone’s assemblies who decided to implement the CLI, or we’d have to make our private key available to the general public, creating a huge security hole.  However, since strong names of referenced assemblies are burned into assemblies at compile time, there needs to be some way for compiler to refer to the standard libraries without forcing a specific implementation of the CLI onto the users of the assembly.

Enter the standard public key.  Assemblies that specify this key as their public key aren’t actually signed by a corresponding private key.  Instead, CLI implantations see this key, and substitute in their own keypair.  For instance, when the SSCLI sees the standard public key, it knows that this means the assemblies have been signed with the key found in sscli\clr\src\dlls\mscorsn\thekey.h and sscli\clr\bin\finalpublickey.snk.

Allowing CLI implementors to swap the actual key that the standard public key represents frees them up to be able to run code that was compiled against another vendor’s CLI implementation.  Also, since each VM implementation will translate the standard public key into only their private keypair, this prevents assemblies signed by creators of CLI implementations from verifying on different CLI implementations.  For instance, the Mono mscorlib won’t pass signature verification on the CLR.

Comments (3)

  1. Dave Thomas says:

    Will this key be translated during runtime to the correct keyblob?

    I.e. could you use it on say a Demand to only allow the ECMA signed assemblys…


  2. Shawn says:

    Hi Dave,

    You can definately use it in a demand. As far as your code is concerned the standard key and token are what the assemblies are signed with. Only internally does the CLR make the switch, so you should never be aware of it.