.NET:CLR via C# Shared Assemblies and Strongly Named Assemblies
Two Kinds of Assemblies, Two Kinds of Deployment

A strongly named assembly consists of four attributes that uniquely identify the assembly: a file name (without an extension), a version number, a culture identity, and a public key. Because public keys are very large numbers, we frequently use a small hash value derived from a public key. This hash value is called a public key token. The following assembly identity strings (sometimes called an assembly display name) identify four completely different assembly files.
- "MyTypes, Version=1.0.8123.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
- "MyTypes, Version=1.0.8123.0, Culture="en-US", PublicKeyToken=b77a5c561934e089"
- "MyTypes, Version=2.0.1234.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
- "MyTypes, Version=1.0.8123.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
Giving an Assembly a Strong Name
Here’s what it means to sign a file: When you build a strongly named assembly, the assembly’s FileDef manifest metadata table includes the list of all the files that make up the assembly. As each file’s name is added to the manifest, the file’s contents are hashed, and this hash value is stored along with the file’s name in the FileDef table. You can override the default hash algorithm used with AL.exe’s /algid switch or apply the assembly-level System.Reflection.AssemblyAlgorithmIdAttribute custom attribute in one of the assembly’s source code files. By default, a SHA-1 algorithm is used.
After the PE file containing the manifest is built, the PE file’s entire contents (except for any Authenticode Signature, the assembly’s strong name data, and the PE header checksum) are hashed, as shown in Figure 3-1. This hash value is signed with the publisher’s private key, and the resulting RSA digital signature is stored in a reserved section (not included in the hash) within the PE file. The CLR header of the PE file is updated to reflect where the digital signature is embedded within the file.

when you compile your source code, the compiler detects the types and members that your code references. You must specify the referenced assemblies to the compiler. For the C# compiler, you use the /reference compiler switch. Part of the compiler’s job is to emit an AssemblyRef metadata table inside the resulting managed module. Each entry in the AssemblyRef metadata table indicates the referenced assembly’s name (without path and extension), version number, culture, and public key information.
AssemblyRef #1 (23000001)
-------------------------------------------------------
Token: 0x23000001
Public Key or Token: b7 7a 5c 56 19 34 e0 89
Name: mscorlib
Version: 4.0.0.0
Major Version: 0x00000004
Minor Version: 0x00000000
Build Number: 0x00000000
Revision Number: 0x00000000
Locale: <null>
HashValue Blob:
Flags: [none] (00000000)
Assembly
-------------------------------------------------------
Token: 0x20000001
Name : L
Public Key : 00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 00 24 00 00 52 53 41 31
: 00 04 00 00 01 00 01 00 bb ee e9 61 d3 89 57 8a 23 34 b6 00 c7 31 f6 d1
: 9b 76 02 06 c7 b4 ff 8f 96 3a 53 c6 dc 96 c9 19 70 55 4b f2 8f 0f 83 9b
: c3 29 f5 89 3b 64 96 41 fd 79 1b ff 5e f6 c1 e0 1b 5e a0 c8 d0 18 b8 74
: 41 d2 ef 78 55 9b 3d ff 18 a6 76 fa 4e 0d 73 89 2b 53 1f d5 b0 1c 27 72
: ae 9e f6 ad 90 04 7b 86 d3 a5 01 a9 f7 a0 1b e0 bb 2b 99 9f ce 30 4b c2
: d9 b9 c2 20 b8 40 0a 76 a2 23 ae 25 02 93 1b d9
Hash Algorithm : 0x00008004
Version: 1.0.0.0
Major Version: 0x00000001
Minor Version: 0x00000000
Build Number: 0x00000000
Revision Number: 0x00000000
Locale: <null>
Flags : [PublicKey] (00000001)
Strongly Named Assemblies Are Tamper-Resistant
Signing an assembly with a private key and embedding the signature and public key within an assembly allows the CLR to verify that the assembly has not been modified or corrupted. When an assembly is installed into the GAC, the system hashes the contents of the file containing the manifest and compares the hash value with the RSA digital signature value embedded within the PE file (after unsigning it with the public key). If the values are identical, the file’s contents haven’t been tampered with. In addition, the system hashes the contents of the assembly’s other files and compares the hash values with the hash values stored in the manifest file’s FileDef table. If any of the hash values don’t match, at least one of the assembly’s files has been tampered with, and the assembly will fail to install into the GAC.
When strongly named assembly files are loaded from a location other than the GAC (via the application’s base directory or via a codeBase element in a configuration file), the CLR compares hash values when the assembly is loaded. In other words, a hash of the file is performed every time an application executes and loads the assembly. This performance hit is a tradeoff for being certain that the assembly file’s content hasn’t been tampered with. When the CLR detects mismatched hash values at run time, it throws a System.IO.FileLoadException.
When a strongly named assembly is installed in the GAC, the system ensures that the file containing the manifest hasn’t been tampered with. This check occurs only once, at installation time. In addition, to improve performance, the CLR does not check if a strongly named assembly has been tampered with if the assembly is fully trusted and is being loaded into a fully trusted AppDomain. On the other hand, when a strongly named assembly is loaded from a directory other than the GAC, the CLR verifies the assembly’s manifest file to ensure that the file’s contents have not been tampered with, causing an additional performance hit every time this file is loaded.
Privately Deploying Strongly Named Assemblies
In addition to deploying a strongly named assembly in the GAC or privately, a strongly named assembly can be deployed to some arbitrary directory that a small set of applications know about.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="D_" />
<dependentAssembly>
<assemblyIdentity name="L" publicKeyToken="357f90d80abcd77e" culture="neutral" />
<codeBase version="1.0.0.0" href="file:///E:/Coding/HappyStudy/AssemblyStudy/L/bin/Debug/L.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
How the Runtime Resolves Type References
When resolving a referenced type, the CLR can find the type in one of three places:
- Same file Access to a type that is in the same file is determined at compile time (sometimes referred to as early bound). The type is loaded out of the file directly, and execution continues.
- Different file, same assembly The runtime ensures that the file being referenced is, in fact, in the assembly’s ModuleRef table of the current assembly’s manifest. The runtime then looks in the directory where the assembly’s manifest file was loaded. The file is loaded, its hash value is checked to ensure the file’s integrity, the type’s member is found, and execution continues.
- Different file, different assembly When a referenced type is in a different assembly’s file, the runtime loads the file that contains the referenced assembly’s manifest. If this file doesn’t contain the type, the appropriate file is loaded. The type’s member is found, and execution continues.
If any errors occur while resolving a type reference—file can’t be found, file can’t be loaded, hash mismatch, and so on—an appropriate exception is thrown.
If you want, your code can register callback methods with System.AppDomain’s AssemblyResolve, ReflectionOnlyAssemblyResolve, and TypeResolve events. In your callback methods, you can execute code that resolves the binding problem and allows the application to continue running without throwing an exception.

Advanced Administrative Control (Configuration)
<?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="AuxFiles;bin\subdir" />
<dependentAssembly>
<assemblyIdentity name="SomeClassLibrary"
publicKeyToken="32ab4ba45e0a69a1" culture="neutral"/>
<bindingRedirect
oldVersion="1.0.0.0" newVersion="2.0.0.0" />
<codeBase version="2.0.0.0"
href="http://www.Wintellect.com/SomeClassLibrary.dll" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="TypeLib"
publicKeyToken="1f2e74e897abbcfe" culture="neutral"/>
<bindingRedirect
oldVersion="3.0.0.0-3.5.0.0" newVersion="4.0.0.0" />
<publisherPolicy apply="no" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
This XML file gives a wealth of information to the CLR. Here’s what it says:
- probing element Look in the application base directory’s AuxFiles and bin\subdir subdirectories when trying to find a weakly named assembly. For strongly named assemblies, the CLR looks in the GAC or in the URL specified by the codeBase element. The CLR looks in the application’s private paths for a strongly named assembly only if no codeBase element is specified.
- First dependentAssembly, assemblyIdentity, and bindingRedirect elements When attempting to locate version 1.0.0.0 of the culture-neutral SomeClassLibrary assembly published by the organization that controls the 32ab4ba45e0a69a1 public key token, locate version 2.0.0.0 of the same assembly instead.
- codeBase element When attempting to locate version 2.0.0.0 of the culture-neutral Some- ClassLibrary assembly published by the organization that controls the 32ab4ba45e0a69a1 CHAPTER 3 Shared Assemblies and Strongly Named Assemblies 85 public key token, try to find it at the following URL: www.Wintellect.com/SomeClassLibrary.dll. Although a codeBase element can also be used with weakly named assemblies. In this case, the assembly’s version number is ignored and should be omitted from the XML’s codeBase element. Also, the codeBase URL must refer to a directory under the application’s base directory.
- Second dependentAssembly, assemblyIdentity, and bindingRedirect elements When attempting to locate version 3.0.0.0 through version 3.5.0.0 inclusive of the culture-neutral TypeLib assembly published by the organization that controls the 1f2e74e897abbcfe public key token, locate version 4.0.0.0 of the same assembly instead.
- publisherPolicy element If the organization that produces the TypeLib assembly has deployed a publisher policy file (described in the next section), the CLR should ignore this file.
When compiling a method, the CLR determines the types and members being referenced. Using this information, the runtime determines, by looking in the referencing assembly’s AssemblyRef table, the assembly that was originally referenced when the calling assembly was built. The CLR then looks up the assembly/version in the application’s configuration file and applies any version number redirections; the CLR is now looking for this assembly/version.
If the publisherPolicy element's apply attribute is set to yes—or if the element is omitted— the CLR examines the GAC for the new assembly/version and applies any version number redirections that the publisher of the assembly feels is necessary; the CLR is now looking for this assembly/version. Finally, the CLR looks up the new assembly/ version in the machine’s Machine.config file and applies any version number redirections there.
At this point, the CLR knows the version of the assembly that it should load, and it attempts to load the assembly from the GAC. If the assembly isn’t in the GAC, and if there is no codeBase element, the CLR probes for the assembly. If the configuration file that performs the last redirection also contains a codeBase element, the CLR attempts to load the assembly from the codeBase element’s specified URL.
Publisher Policy Control
In the scenario described in the previous section, the publisher of an assembly simply sent a new version of the assembly to the administrator, who installed the assembly and manually edited the application’s or machine’s XML configuration files. In general, when a publisher fixes a bug in an assembly, the publisher would like an easy way to package and distribute the new assembly to all of the users. But the publisher also needs a way to tell each user’s CLR to use the new assembly version instead of the old assembly version. Sure, each user could modify his or her application’s or machine’s XML configuration file, but this is terribly inconvenient and error prone. What the publisher needs is a way to create policy information that is installed on the user’s computer when the new assembly is installed. In this section, I’ll show how an assembly’s publisher can create this policy information.
A publisher policy assembly is a way for a publisher to make a statement about the compatibility of different versions of an assembly. If a new version of an assembly isn’t intended to be compatible with an earlier version, the publisher shouldn’t create a publisher policy assembly. In general, use a publisher policy assembly when you build a new version of your assembly that fixes a bug. You should test the new version of the assembly for backward compatibility. On the other hand, if you’re adding new features to your assembly, you should consider the assembly to have no relationship to a previous version, and you shouldn’t ship a publisher policy assembly. In addition, there’s no need to do any backward compatibility testing with such an assembly.
.NET:CLR via C# Shared Assemblies and Strongly Named Assemblies的更多相关文章
- CLR via C# 3rd - 03 - Shared Assemblies and Strongly Named Assemblies
1. Weakly Named Assembly vs Strong Named Assembly Weakly named assemblies and strongly named ...
- Shared Assembilies and Strongly Named Assemblies
the .NET Framework has in place to deal with versioning problems. Two Kinds of Assemblies, Two Kinds ...
- Chapter 3 Shared Assemblies and Strongly Named Assemblies
As time marches on,MS developers and control developer modify their code:they fix bugs,patch securit ...
- SpringCloud报错:com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server
启动SpringCloudEureka 报错:com.netflix.discovery.shared.transport.TransportException: Cannot execute req ...
- .NET:CLR via C# Manifest
An assembly is a collection of one or more files containing type definitions and resource files. One ...
- 启动MongoDB时,提示:error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
启动MongoDB时,提示: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: ...
- constant timer(固定定时器),constant throughput timer(常数吞吐量定时器);多个请求,某个请求a下,设置常数吞吐量定时器,模式:all active threads(shared)则所有请求吞吐量一致;
1.两请求之间添加'固定定时器' 1000ms,那么两请求发送间隔时间是多少? 1000ms吗? 由实验得出,2个请求发送间隔时间 = 1000ms + 第一个请求时间(发出至完成后时间) 2.单个请 ...
- linux下报错:error while loading shared libraries
linux执行bin程序报: error while loading shared libraries:libncurses.so.5: cannot open shared object file: ...
- 在eclipse中,Python项目遇到:…… from appium import webdriver ImportError: No module named appium
1) Traceback (most recent call last): File "D:\python workspace\src\p_test01\__init__.py" ...
随机推荐
- Winafl学习笔记
最近在跟师傅们学习Winafl,也去搜集了一些资料,有了一些自己的理解,就此记录一下. Winafl是一个运行时插桩工具,可以提高crash的捕获率. 同时也有自己的遗传算法,可以根据代码覆盖程度进行 ...
- HTML5练习2
1.邮箱注册网页 主要代码: <!doctype html> <html> <meta charset="utf-8"> <title&g ...
- markdown转换为html
想要自己实现markdown编辑器,欲使用markdown-it作为编辑器,有着比较多的插件,可以实现代码高亮以及对数学公式转换等功能. // Activate/deactivate rules, w ...
- 【LOJ】#2497. 「PA 2017」Banany
题解 一眼就是线段树维护点分树的dfs序嘛 代码debug一年(手动再见) 码力直线下降,坐等滚粗= = 很明显的我们需要一个点分树,然后求出以每个重心为根的树的dfs序,线段树维护一下每个点的价值- ...
- RabbitMQ 相关理论部分
集群配置方式 RabbitMQ可以通过三种方法来部署分布式集群系统,分别是:cluster,federation,shovel cluster: 不支持跨网段,用于同一个网段内的局域网 可以随意的动态 ...
- Linq To Sql 使用初探
最近有数据处理需要,就是那种从数据库中把数据取出来 ,对其中的部分字段做一些处理再吐回去的工作,从同事那里学习到了,这中活最适合使用 Linq to Sql 这种方式,不用搭建框架,不用自建实体,直接 ...
- Bootstrap进阶六:动态样式语言LESS简介
LESS 将 CSS 赋予了动态语言的特性,如 变量, 继承, 运算, 函数. LESS 既可以在 客户端 上运行 (支持IE 6+, Webkit, Firefox),也可以借助Node.js或者R ...
- ubuntu16.04 安装symfony3.3.11 碰到的问题:extension dom is required | oops an error occurred 500
问题1:Uncaught exception 'RuntimeException' with message 'Extension DOM is required' 解决:sudo apt-get i ...
- web服务端安全之暴力破解
一.暴力破解 指攻击者通过遍历或字典的方式,向目标发起大量请求,通过判断返回数据包的特征来找出正确的验证信息,从而绕过验证机制. 二.常见场景 用户登录处的账号密码暴力破解: 人机验证机制容易绕过,如 ...
- Navicat Premium 激活码 序列号。破解版。
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha Navicat Premium 激活码 序列号.破解版.