The main purpose of a
strong name or assembly signature is its uniqueness in the
GAC (
Global assembly cache ). Based on the assembly, a cryptographic public key is calculated during the signature, the private one is kept secret with the manufacturer of the assembly, the hash function of which is
public token , which, in fact, has a strong name for the assembly.
The public token is stored in the build metadata and paired with the build name, version, and culture, and serves to uniquely identify it.
There is no doubt that this mechanism is very suitable for the unique identification of assemblies and the use of the same assembly by different applications.
But many are mistaken in thinking that an assembly with a strong name is protected from modification. In fairness, it is worth noting that if the manufacturer of the assembly has published a
public token or a public key, for example, on its website, then you can always check if this key or token matches the key that is sewn into the used assemblies, but you will probably have to check it manually. The important thing is that the strong name will not protect the assembly from modification, as many think, and accordingly the mechanism in the
CLR will not work as expected and load the modified assembly.
')
How is this possible you ask? It's very simple, since the Public token (public key token) is sewn into the assembly, you can simply remove it from there.
But after all, other assemblies that refer to this assembly and its strong name will not load it and will not be executed properly, you say. Yes, do not upload. As long as they are also signed with a strong name and while dependencies they have this build. But if these assemblies have strict names or links to assemblies removed and replaced with the same ones only without a strong name, then the application will work as it should.
However, it should first be noted that everything described above works when you have access to assemblies for modification. If, for example, this is a web service, then these assemblies cannot be accessed.
Let's look at an example. Let some company produces its product. No matter what. What is important is that their product consists of a certain number of their own assemblies signed with one private key, and therefore with the same
public token . Also their product contains
3rd party assemblies, third-
party assemblies, components that come with the product. The company decides to somehow limit the functionality of the product, of course the code restrictions and the conditions under which it works, are in the assemblies of the company. An attacker needs to modify any one assembly to remove the restriction. He modifies it and removes the strong name, so that the assembly will not be signed. In order for other assemblies that refer to it to work properly, it will remove the signature from them as well, and also change the dependencies of these assemblies for unsigned assemblies.
Perhaps you think it is difficult to do? No, this can make any student. What is needed for this? Reflex and
ReflexIL plug-in for it.
ReflexIL has a strong name remover. It works very simply. Select the assembly, click "
Auto scan assembly directory ", if the assemblies with a strong name are found, they will be added to the list. And then click "
Remove strong name and update referencing assemblies " and that's it. Now we have removed the signature from the assembly.

Those. Despite the fact that we are assured that a strong name in addition to its relation to the global cache of assemblies also protects against modification of the assembly, this is not so in practice.
So you should not rely on a strong name as a reliable protection against modification.
But what about you? In fact, this is the topic of another article. But the answer is clear, use the standard for .NET protection mechanisms - obfuscation, the use of mixed managed and unmanaged code.
You can also check the strong name of the assembly manually, and in combination with
PostSharp or some other AOP approach, mark the necessary methods in the code with an attribute indicating that you need to check the strong name before calling it. And check with your own method the strong name of the assembly with a hard-wired constant. Only with this, the pieces of the code with the check and call of the check, as well as the constant with the public token should be obfuscated and encrypted. Or rethink the product and make some of its parts as web services, although this is not always possible. You can manually check the strong name in the following way.
private static bool IsPublicTokenValid( byte [] tokenExpected)
{
// Retrieve token from current assembly
byte [] tokenCurrent = Assembly .GetExecutingAssembly().GetName().GetPublicKeyToken();
// Check that lengths match
if (tokenExpected.Length == tokenCurrent.Length)
{
// Check that token contents match
for ( int i = 0; i < tokenCurrent.Length; i++)
if (tokenExpected[i] != tokenCurrent[i])
return false ;
}
else
{
return false ;
}
return true ;
}
So what does a strong name protect against? Roughly speaking, from nothing. This is a means to uniquely identify assemblies, with which several versions of the same assemblies in the
GAC can coexist.
Does a strong name help protect against assembly modifications? A strict name
cannot protect against spoofing an assembly; it will not stop the attacker from deleting the assembly's signature, over-signing the assembly with his own key and distributing it in this form. True, the re-signed assembly will have a different public key, which can be manually compared with the publisher's public key.
Is it possible to use the assembly signature with a strong name to determine the author of the assembly ? A strong name does not imply a level of trust in an assembly that provides, for example,
Authenticode .