StrongProgramSet Name
As previously mentioned, private Assembly resides in the client application folder, while shared Assembly resides in GAC. Although private assembly can be used directly and simply, shared assembly should be considered in the following two cases. The first case is that different versions of the same assembly can be used at the same time. The second scenario is to share an assembly between multiple client applications. Sharing means that an improved and compatible assembly can be made available to multiple applications as soon as possible without separately patching the private assembly of each application. Frameworks and class library providers tend to use them in a shared manner.
To enable GAC to include assemblies from multiple providers,. NET must provide a way to uniquely identify shared assemblies. A friendly name for "myassembly", for example, is not enough, because multiple providers can obtain the same friendly name. Therefore,. NET must ensure the uniqueness of the Assembly in one way. Com uses "globally unique identifiers (globally unique identifier guids)"-a unique 128-bit number to assign each component. Using guids is simple, but there is a fatal flaw: Any group can see it, copy it, and replace it with a new potential malicious component that uses the replicated guids. The guids of COM can provide a unique identifier, because there is only one component registered with a given guids at any time and on any computer. However, guids does not provide authenticity and integrity.
To ensure uniqueness and authenticity,. Net shared Assembly must include the unique proof of their creator and original content. Such proof is called "Strong name (strong name )".. Net uses a pair of encryption keys to create a strong name, a public key and a private key. Except for the specified method, the Private Key has nothing special. This is very important for public and private keys. No matter which key is used for encryption, another key must be used for decryption. For example, any data encrypted by a private key must be decrypted by a public key instead of itself.
During compilation, the compiler uses a private key to encrypt the hash value of the Assembly (the Assembly List includes not only the friendly name and version number of the Assembly, but also the hash value of the module that makes up the Assembly ). In this way, the encryption result is unique and the source and content digital signature is ensured at the same time. The compiler then appends the signature and public key to the assembly list. Each client can access the public key. On the other hand, private keys should be kept inaccessible. During compilation, in addition to the version number, the strongly-naming Assembly referenced by the client records a tag representing the public key of the server Assembly in its assembly list:
. Assembly extern myserverassembly
{
. Publickeytoken = (22 90 49 07 87 53 81 98)
. Ver 1: 2: 3: 4
}
When the client assembly is triggered. net to find the server assembly, if a matching assembly is found ,. net will read its public key and calculate the tag, compare it with the client's expected assembly information. Then,. Net decrypts the digital signature using the public key, and compares the hash value of the Assembly in the digital signature with the hash value of the detected assembly. If two matches, they are the expected assembly of the client. Because the private key is unique and saved by the organization where it is created, a strong name ensures that no one can use the same digital signature to generate an assembly ,.. Net also maintains uniqueness and authenticity.
A named assembly can be referenced by any strongly-named Assembly, such as an assembly in. NET Framework. However, in turn, it is not correct. A Strongly-named Assembly can only reference other strongly-named assembly. If the type definition used by a program comes from other well-known assemblies, the compiler rejects the generation and assignment of strongly named assemblies. The reason is obvious: a strong name means that the client can trust the authenticity and integrity of the service provider's assembly and obtain the correct version. If the strongly-named assembly can use other potentially unknown and unverified versions of the Assembly, the trust loop will be destroyed. Therefore, a strongly-named Assembly can only reference other strongly-named assembly.
I. Assembly Signature
You can create an encryption key in Visual Studio 2005 to sign the assembly. Select the "signature" Panel in Project Properties and select the "sign for assembly" option box to sign the Assembly using an existing or new key file:
Strong naming key files can be in two formats: plaintext and password protection. If you do not select "use password to protect the key file" when creating the key file, a file with the SNK extension is generated. However, saving a key file in such an original format poses a huge risk: any malicious organization that has leaked the private key can impersonate the component provider to generate the component. Therefore, it is best to use a password to protect the key file. After the password is specified, Visual Studio will generate a file with the pfx extension. When another user uses the file for the first time, password verification is required. After a correct password is provided, Visual Studio extracts the key from the pfx file and stores it in the certificate Container, so that the user no longer needs to provide the password for the second use.
Select an existing strong-name key file
When you select an existing SNK or pfx file, Visual Studio automatically copies the file to the project folder. There is no way to share this type of file. Each project must have a unique physical copy of the file.
Process keys in an organization
A strong private key for an organization should be properly preserved. If a private key is disclosed, components of an organization with a low reputation can be forged and distributed. Security and credibility (also potential legal responsibility) will be affected. Therefore, access to private keys in an organization must be strictly restricted. It is recommended that you only provide them to the corresponding development team (retain copies at the same time ). However, this may cause some problems: how to execute the intermediate internal generation without a private key? How can I allow the client assembly to reference this assembly? To solve these problems,. NET provides "Delay signing (delayed signature )". When "delayed signature only" is selected in the signature panel, the compiler embeds a public key in the assembly list, but does not generate a digital signature. In this way, the Assembly can be installed in GAC and the client assembly can be referenced to execute internal generation and test cycles. However, the Assembly with delayed signatures cannot be run and debugged, because the strong naming verification process fails during reading.
For delayed signatures, you can use the-p command line switch of the sn.exe utility to extract a public key from a file containing a public and private key to a separate file:
Sn.exe-P mykeys. pfx mypublickey. pfx
In this way, public keys can be freely distributed within the Organization. To run the delayed signature assembly, you must use the-VR command line to disable the digital signature verification of the Assembly:
Sn.exe-VR myassembly. dll
You still need to use the actual private key to sign the Assembly before releasing the assembly. You can select to cancel the authentication only when the signature is delayed. You can also use the sn.exe utility-R command line to switch and re-sign (the key file containing the public key and private key ):
Sn.exe-r myassembly. dll mykeys. pfx
Ii. Strong naming and private assembly
. NET is used to identify a strongly-named private assembly and a common private assembly by checking whether only friendly names are available. If a private assembly only contains a friendly name,. Net records the version of the private assembly in the client assembly list:
. Assembly extern myserverassembly
{
. Ver 1: 2: 3: 4
}
However, in fact. NET will ignore the version incompatibility between the client application and the private assembly, even if the version number is available in the client assembly list. If an application references a private assembly with a friendly name, it will always be used, and. NET will not be searched in GAC. For example, after compiling and deploying a client application with a non-strongly-named private assembly (version 1.0.0.0), you must upgrade it to 2.0.0.0 and copy version 2.0.0.0 to the application folder, it will overwrite 1.0.0.0 at runtime. net will read the new version. If the new version is backward compatible, the application will work very well, but if 2.0.0.0 is not compatible with 1.0.0.0, it will cause confusion. Unlike "DLL hell", this issue does not affect other applications with private copies of different versions of the Assembly .. Net, because it assumes that the client application administrator understands the version, compatibility, and whether it is worth the risk of overwriting the new version.
On the other hand, if a private Assembly contains a strong name,. Net enforces the version compatibility policy .. . Net records the request's private assembly Public Key tag in the client assembly list, and insists on version matching. Return to the example discussed earlier. In this case, the Assembly parser searches for the compatible version of the Assembly in GAC. if the version cannot be found in GAC, an exception is thrown, the private version 2.0.0.0 is considered incompatible. The following important conclusions are obtained:
1. Only private assembly with friendly names must be backward compatible.
2. Private assembly with strong names does not need to be backward compatible, because GAC can contain an earlier compatible version.
3. Even if a private assembly with a strong name is backward compatible, an exception may occur if the version number is incompatible (unless the GAC contains an earlier version ).
4. The private assembly deployment model is only applicable to named assembly.
Iii. Friendly assembly and strong naming
The internalsvisibleto feature can be used to indicate a friendly client assembly. Friendly assembly can access the types and members inside the server assembly. However, a server assembly without a strong name can only indicate a client assembly without a strong name:
[Assembly: internalsvisibleto ("myclient")]
However, this is obviously an insecure and reliable way to expose the internal type of the Assembly. Because of this, third-party assembly can access the internal type of the server assembly by rewriting the Assembly friendly naming method. The use of the internalsvisibleto feature should restrict the development of the Assembly combined with the server assembly. To provide more advanced security to internalsvisibleto, server assembly with strong names can only specify client assembly with strong names as friendly assembly. In this way, both the client Assembly name and strong naming mark must be indicated in the internalsvisibleto feature:
[Assembly: internalsvisibleto ("myclient", publickeytoken = 745901a54f88909b)]
This indicates that only client programs with friendly names and strong names can be authorized to access the server assembly, and the client compiler will ensure this limitation.
4. Install shared assembly
Once a strong name is specified for the Assembly, you can install it to GAC. GAC is located under a special folder named assembly under the Windows folder. There are multiple ways to view and operate GAC .. Net will install a Windows Shell extension to use the file browser to display the Assembly in GAC, you can navigate to GAC and drag the shared assembly to GAC, you can also remove the Assembly from GAC through the file browser. The second operation is the command prompt utility gacutil, which is usually used in the application installer. The third way to manage GAC is to use a dedicated management tool called ". Net Configuration tool", which is a Microsoft Management Console (MMC) unit:
Click "add assembly to application cache" to add shared assembly to GAC. Note: Only members of the system administrator group can add or remove an assembly from GAC. Click "view assembly list in Assembly Cache". The configuration tool displays the view of all the shared assembly in GAC, including the friendly name, version number, region, and public key tag of each Assembly:
Verify the shared Assembly Mode
For some development and debugging purposes, you can verify whether the server assembly is used as a shared assembly by programming. The globalassemblycache Boolean attribute of the assembly type can be used for processing. When the Assembly is read from GAC, globalassemblycache is set to true. You can also use the location attribute to tell the user where the Assembly is actually read. The following is the implementation and use of the assertsharedassembly auxiliary method-verify whether a given assembly is read from GAC. If not, this method will prompt the user and point out the actual location of the Assembly:
Using system. reflection;
Static void assertsharedassembly (Assembly)
{
Bool shared = assembly. globalassemblycache;
Debug. Assert (shared );
If (shared = false)
{
String message = @ "the Assembly shocould not be used as a shared assembly.
It was loaded instead from :";
String currentdir = assembly. location;
MessageBox. Show (Message + currentdir );
}
}
Assembly = assembly. getexecutingassembly ();
Assertsharedassembly (assembly );
Note: WriteCodeYes. For example, the assertsharedassembly () method should only be used to detect errors during development.
Synchronous execution
GAC can store multiple versions with the same named assembly. This is because GAC uses a Windows file system, but it is not a flat structure. When each assembly is added to GAC,. Net creates a set of folders whose paths are composed of the Assembly name, version number, and Assembly Public Key tag. For example:
C: \ windows \ Assembly \ gac_msil \ mysharedassembly \ 1.0.0.0 _ 745901a54f88909b \ mysharedassembly. dll
Therefore, two different versions of the same assembly are placed in two different folders. The client assembly list for each referenced assembly contains the Assembly friendly name, version number, Public Key tag, and other information, which is sufficient for the Assembly parser to locate the correct assembly in GAC and read it. This ensures synchronous execution.
According to the English translation of the original version, please do not correct the deficiencies and errors. Thank you :)