112

What are the advantages of using strong named assemblies?

What are the things that can't be done with a normal assembly?

Mike Dinescu
  • 54,171
  • 16
  • 118
  • 151
developer
  • 3,811
  • 8
  • 31
  • 34

4 Answers4

98

Let me list the benefits of strong naming your assembly first:

  1. Strong naming your assembly allows you to include your assembly into the Global Assembly Cache (GAC). Thus it allows you to share it among multiple applications.

  2. Strong naming guarantees a unique name for that assembly. Thus no one else can use the same assembly name.

  3. Strong name protect the version lineage of an assembly. A strong name can ensure that no one is able to produce a subsequent version of your assembly. Application users are ensured that a version of the assembly they are loading come from the same publisher that created the version the application was built with.

More on strong naming from Microsoft is in Strong-Named Assemblies (MSDN).

Jan Hohenheim
  • 3,552
  • 2
  • 17
  • 42
Kyle Rosendo
  • 25,001
  • 7
  • 80
  • 118
  • 1
    Are you sure on item 4? I think maybe this bahavior has changed recently. I tried to get the loading of an strongly named assembly to fail by modifying it, but it loaded without incident. – Jens Mar 01 '10 at 07:13
  • @Kyle: I tried. Before the modification, sn.exe could verify the strong name, after my modification, the verification failed. It was still loaded by my application without warning message, though. – Jens Mar 01 '10 at 07:53
  • That's why I asked if you do the manual check. You can use the assemblies Evidence object to check the strong name hash. – Kyle Rosendo Mar 01 '10 at 08:09
  • 19
    With regards to #4 that is incorrect. It is not designed to protect against tampering. See http://blogs.msdn.com/b/shawnfa/archive/2005/12/13/authenticode-and-assemblies.aspx for more. – Colin Bowern Jan 24 '13 at 15:19
  • Perhaps then the question should be, why wouldn't you strongly name every project? What are the advantages of not doing so – userSteve Sep 11 '14 at 12:32
  • @user1722957 You could use more NuGet packages then. Some non-strongnamed packages "XYZ" have also a "XYZ-Signed" package on NuGet, but many have not. – springy76 Sep 11 '14 at 17:05
  • Binding Redirects negate any security advantages for Strong Naming. They can tamper with and replace your dependencies by just adding a binding redirect. – trampster Mar 30 '17 at 04:17
  • @trampster - An Assembly Binding Redirect of a strongly named assembly requires all redirected assemblies to use the same Assembly Qualified Name, including the PublicKeyToken. How would using a Binding Redirect allow you to circumvent Assembly Verification without having the original private key? – RobV8R Jan 17 '18 at 18:32
  • 1
    @RobV8R 90% of our dependencies are opensource, the private keys are in the public git repos (as per Microsoft recommendations) and available to anyone who wants them. – trampster Jan 18 '18 at 20:52
  • @trampster - If the Strong Name private key is compromised, you wouldn't need a Binding Redirect. You could either disassemble, modify, and recompile the assembly (with any extra code you want) or use an IL weaver to modify the CIL/MSIL code and then re-sign the assembly with the private key. Because you need the private key and do not require a Binding Redirect to modify the assembly, I still disagree with your statement that "Binding Redirects negate any security advantages for Strong Naming." – RobV8R Jan 19 '18 at 22:08
  • 1
    @RobV8R You can't use the word compromised here, that would imply that it is intended to be a secret in the first place. Microsoft guidelines are that the private key should be kept in you public source repository. The private keys are not compromised they are intentionally published. Given that the private keys are known, and intended to be used by people modifying the opensource code of parent projects (otherwise the license would be violated in many cases) then people doing this would use a different version number but the same key, in this case a binding redirect would be required. – trampster Jan 21 '18 at 21:27
  • 1
    @RobV8R What I was originally getting at is that many people believe that strong naming guarantees that your dependency is locked to a specific version of an assembly, and that is simply not the case, a simple binding redirect can change the version you use provided it was signed with the same private key. And as I have said the private keys are intentionally published for most of our dependencies. – trampster Jan 21 '18 at 21:31
  • @Everyone - Publishing Private Keys is BAD! They are named "Private" for a VERY good reason. – RobV8R Jun 15 '18 at 12:31
  • 1
    @Everyone - Now that Microsoft guidelines are that the private key should be kept in you public source repository, what are the remaining benefits of using strongly named assemblies except that they can be installed to GAC? – Zhiliang Oct 03 '18 at 13:25
10

What are the things that can't be done with a normal assembly?

Since all the discussions that started with the rise of Nuget suggested to completely get rid of strong named assemblies my company tried that and came across a significant change of behavior when it comes to application settings:

If you use the automatic app or user scoped application settings provided by VisualStudio (inheriting System.Configuration.ApplicationSettingsBase) then a strong named EXE will create exactly 1 directory inside %LOCALAPPDATA% named for example "YourApplication.exe_StrongName_kjsdfzsuzdfiuzgpoisdiufzsdouif" no matter where the EXE is located.

But without the strong name the location (=path) of the EXE will be used to create a hash value which already differs between DEBUG and RELEASE build, creating many directories inside %LOCALAPPDATA% named like "YourApplication.exe_Url_dfg8778d6fs7g6d7f8g69sdf". This makes it unusable for ClickOnce deployments where the installation directory changes with every update.

springy76
  • 3,706
  • 2
  • 24
  • 46
6

I would like to add that without a strong name you cannot use binding redirects in config files.

This will not work:

  <dependentAssembly>
    <assemblyIdentity name="MyAssembly.MyComponent" publicKeyToken="null" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
  </dependentAssembly>

You need to have a public key token

  <dependentAssembly>
    <assemblyIdentity name="MyAssembly.MyComponent" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
  </dependentAssembly>
tomasat
  • 578
  • 8
  • 11
0

Just an example: I would like to give an answer doing more emphasis in the security. In the case we create assemblies with a source code that we don't want to be re-used for a third party but we want it to be testable, we can strongly sign an assembly and make the internals visible for only those assemblies with the same signature.

Ricky Youssef
  • 228
  • 4
  • 10