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的更多相关文章

  1. 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 ...

  2. Shared Assembilies and Strongly Named Assemblies

    the .NET Framework has in place to deal with versioning problems. Two Kinds of Assemblies, Two Kinds ...

  3. 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 ...

  4. SpringCloud报错:com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server

    启动SpringCloudEureka 报错:com.netflix.discovery.shared.transport.TransportException: Cannot execute req ...

  5. .NET:CLR via C# Manifest

    An assembly is a collection of one or more files containing type definitions and resource files. One ...

  6. 启动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: ...

  7. constant timer(固定定时器),constant throughput timer(常数吞吐量定时器);多个请求,某个请求a下,设置常数吞吐量定时器,模式:all active threads(shared)则所有请求吞吐量一致;

    1.两请求之间添加'固定定时器' 1000ms,那么两请求发送间隔时间是多少? 1000ms吗? 由实验得出,2个请求发送间隔时间 = 1000ms + 第一个请求时间(发出至完成后时间) 2.单个请 ...

  8. linux下报错:error while loading shared libraries

    linux执行bin程序报: error while loading shared libraries:libncurses.so.5: cannot open shared object file: ...

  9. 在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" ...

随机推荐

  1. python 库资源大全

    偶然的机会翻到这篇文章,很全面,来源:  Python 资源大全中文版       哪些 Python 库让你相见恨晚? 环境管理 管理 Python 版本和环境的工具 p:非常简单的交互式 pyth ...

  2. USACO 4.3 Street Race

    Street RaceIOI'95 Figure 1 gives an example of a course for a street race. You see some points, labe ...

  3. Ubuntu16.04下Hive的安装与配置

    一.系统环境 os : Ubuntu 16.04 LTS 64bit jdk : 1.8.0_161 hadoop : 2.6.4mysql : 5.7.21 hive : 2.1.0 在配置hive ...

  4. 常见的mysql数据库sql语句的编写和运行结果

    省份城市试题#省份表    -> select * from province;+----+----------+| id | province |+----+----------+|  1 | ...

  5. Think PHP 3.2 界面及JS多语言实现

    1.多语言实现的原理在实现多语言的时候需要调用L()函数.那么L函数是如何实现多语言的输出呢?在L函数内部有一个静态变量$_lang一维数组.所有的语言数据都存在在这个数组中.系统在加载的时候根据选择 ...

  6. 2011年入侵 Kernel.org 的黑客被捕 面临10年监禁

    2011年中旬,Linux内核官网kernel.org遭到黑客入侵,攻击者植入了rootkit Phalanx,并在服务器上设置了SSH后门,kernel.org为此关闭了三周多时间.官方表示将会公开 ...

  7. Object-c和Java中的代理

    代理模式的核心思想就是一个类想做一件事情(函数),但它不去亲自做(实现),而是通过委托别的类(代理类)来完成. 代理模式的优点: 1.可以实现传值,尤其是当一个对象无法直接获取到另一个对象的指针,又希 ...

  8. Django-url反向解析与csrf-token设置

    url反向解析 在使用Django 项目时,一个常见的需求是获得URL 的最终形式,以用于嵌入到生成的内容中(视图中和显示给用户的URL等)或者用于处理服务器端的导航(重定向等). 人们强烈希望不要硬 ...

  9. [Luogu5106]dkw的lcm

    https://minamoto.blog.luogu.org/solution-p5106 容易想到枚举质因子及其次数计算其贡献,容斥计算$\varphi(p^i)$的次方数. #include&l ...

  10. BZOJ 4520 [Cqoi2016]K远点对(KD树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4520 [题目大意] 求K远点对距离 [题解] 修改估价函数为欧式上界估价,对每个点进行 ...