The publisher's public key is embedded in the assembly's metadata along with the other components of the assembly name (text name, version and culture). But it is not enough to simply supply the public key in this fashion. After all, the key is public and therefore nothing would stop another publisher from stamping its assemblies with your key. To enforce the strength of the name, you must be able to verify that the contents of the assembly were indeed generated by the advertised publisher.
It's important that the entire content of the assembly (including external modules for multifile assemblies) are covered by this verification. Otherwise, a malicious third party could modify a valid assembly and redistribute the result. Even innocuous-seeming aspects of the assembly, such as user interface resources, are potential security vulnerabilities if left open to modification by third parties. For example, simply changing the text of a dialog prompt could trick a user into revealing password information, potentially in a publicly visible manner. See Figure 9.4 for an example.
To tie together the publisher identity—the public key—and the contents of the assembly, a digital signature is computed and written into the assembly during compilation. The signature is formed by computing a cryptographic hash over the contents of the assembly (essentially, a very condensed summary of the data) and encoding the result using the publisher's private key. Figure 9.5 illustrates the signing process.
To perform validation, the signature is decrypted using the publisher public key (found in the assembly metadata), yielding an assembly contents hash. The hash is then recomputed for the current assembly contents and the results compared. If both hashes match, you know that the current assembly contents remain identical with those from the point at which the signature was generated. Furthermore, you know that the generator of the signature was in possession of the private key corresponding to the public key found in the assembly manifest. Figure 9.6 depicts the verification process. Any attempt to modify the assembly contents will change the hash generated on verification, and storing an updated hash for the new contents requires the private key for the hash encryption phase.
From this you can see that the reliability of strong name verification is dependent on two factors—the secrecy of the private key and the ability of the hash to accurately reflect the contents of the assembly. The hashing algorithm used is SHA1, which generates a 20-byte hash code. It is extremely difficult, in fact computationally unfeasible, to discover another byte sequence that will yield the same hash code under this algorithm—changing even a single bit in the input will yield a radically different hash.
In summary, the act of strong naming requires the addition of two new pieces of data to the assembly:
The public key, which becomes visible as part of the assembly's name
The signature, which validates the right to use the public key and allows the consistency of the assembly contents to be verified
The structure of a strong name assembly is illustrated in Figure 9.7.
The verification of any strong name assemblies is performed automatically when needed by the .NET Framework. Any assembly claiming a strong name but failing verification will fail to install into the global assembly or download cache or will fail to load at runtime.
3.145.186.6