What does strong name protect in .net assemblies?

    The main goal 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 key is kept secret from the assembly manufacturer, the hash function of which is public token , which, in fact, is a strong name for the assembly. The public token is stored in assembly metadata and paired with the assembly name, version, and culture, and serves to uniquely identify it.

    There is no doubt that such a 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 published a public token or public key, for example, on its website, then you can always check whether this key or token matches the key that is wired into the used assemblies, but it will probably have to be checked manually. Another important thing is that a strong name will not protect the assembly from modification, as many people think, and accordingly the mechanism in the CLR will not work as it should and load the modified assembly.

    How is this possible you ask? Everything is very simple, since the Public token (public key token) is sewn into the assembly, you can simply remove it from there.

    But other assemblies that reference this assembly and its strict name will not load it and will not be executed, as you should, you say. Yes they will not download. While they are also signed with a strong name, and while in the dependencies they have this assembly specified. But if you remove strict names or references to assemblies from these assemblies and replace them with the same ones without a strong name, then the application will work as it should.

    True, it should be noted first that everything described above works when u has access to assemblies for modification. If, for example, this is a web service, then there is no way to access these assemblies.

    Let's look at an example. Let a company release its product. No matter what. Another important thing 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 partyassemblies, third-party assemblies, components that come with the product. The company decides to somehow limit the functionality of the product, naturally the restriction code and the conditions under which it works are in the company's assemblies. An attacker needs to modify a single assembly to remove the restriction. He modifies it and removes the strict name, so that the assembly will not be signed. In order for other assemblies that reference it to work correctly, he will remove the signature from them as well, and also change the dependencies of these assemblies to assemblies without a signature.

    Perhaps you think this is difficult to do? No, any student can do this. What is needed for this? Reflector and plugin for it ReflexIL .

    As part of ReflexILthere is a strong name remover. It works very simply. We select the assembly, click " Auto scan assembly directory ", if 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.

    image

    Those. in spite of the fact that they assure us that a strict name, in addition to its relation to the global assembly cache, also protects against assembly modification, this is far from the case in practice.
    So you should not rely on a strict name as a reliable protection against modification.
    But what about you ask? In fact, this is the topic of another article. But the answer is clear, use standard protection mechanisms for .NET - 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 must 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 in this case the pieces of code with verification and verification call, as well as a constant with public token should be encrypted obfuscated. Or rethink the product and take out some of its parts as web services, although this is not always possible. You can manually verify a 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 strict name protect from? Roughly speaking, from nothing. This is a tool for uniquely identifying assemblies that can coexist multiple versions of the same assemblies in the GAC .

    Does a strong name help protect against assembly modification? A strict name cannot protect against assembly spoofing; it will not stop an attacker from deleting the signature of the assembly, re-signing the assembly with its own key, and distributing it in this form. True, the re-signed assembly will have another public key, which can be manually compared with the public key of the publisher of the assembly.

    Is it possible to use the assembly signature with a strong name to determine the author of the assembly? A strict name does not imply a level of trust in the assembly, which is provided, for example, by Authenticode .

    Also popular now: