Could not load file or assembly 'System.Security.Cryptography.Algorithms, Version = 4.1.0.0
Asked Answered
R

4

16

I'm trying to use System.Security.Cryptography.RNGCryptoServiceProvider class in my .NET Standard 1.4 library and according to this topic my code looks like this:

    private byte[] GenerateRandomNumber(int length)
    {
        using (var randomNumberGenerator = RandomNumberGenerator.Create())
        {
            var number = new byte[length];
            randomNumberGenerator.GetBytes(number);

            return number;
        }
    }

I have also installed from NuGet libraries:

  • System.Security.Cryptography.Algorithms v=4.3.0
  • System.Security.Cryptography.Primitives v=4.3.0

But trying fire it up gives me:

'Could not load file or package' System.Security.Cryptography.Algorithms, Version = 4.1.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a 'or one of its dependencies. The specified file could not be found. '

And on NuGet page there is no 4.1.0.0 version, only 4.1.0-rc2-24027 and after installing this version I get exact same exception.

What is wrong?

Edit: Switching from .NET Standard 1.4 to 1.6 didn't help

Edit2:

When I hit F12 on RandomNumberGenerator:

#region Assembly System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// C:\Users\x.y\.nuget\packages\system.security.cryptography.algorithms\4.3.0\ref\netstandard1.4\System.Security.Cryptography.Algorithms.dll
#endregion

namespace System.Security.Cryptography
{
    public abstract class RandomNumberGenerator : IDisposable
    {
        protected RandomNumberGenerator();

        public static RandomNumberGenerator Create();
        public void Dispose();
        public abstract void GetBytes(byte[] data);
        protected virtual void Dispose(bool disposing);
    }
}

So it wants 4.1.0 version (that not exists on NuGet) but path is set for 4.3.0

Robison answered 5/9, 2017 at 9:43 Comment(6)
It says it has the following dependencies for .NET Standard 1.4, have you added these references as well? System.IO (>= 4.3.0), System.Runtime (>= 4.3.0), System.Security.Cryptography.Primitives (>= 4.3.0)Lexicologist
Yes I have System.IO 4.3.0, System.Runtime 4.3.0 and System.Security.Cryptography.Primitives 4.3.0Robison
I suggest that you use the Fusion Log Viewer to get details about the loading error. Most likely the version of the assembly in your bin folder is not the same as the requested version even though it is compatible. You then have to add a binding redirect in your app.config redirecting the desired version to the actual version.Manes
Fusion Log Viewer don't show any data about it (maybe it's because program throws System.IO.FileNotFoundException?) and if it goes for binding redirect I'm currently running this code from unit test so i believe it wont work there.Robison
@Carlos28: I can confirm that Fusion Log Viewer seems to not always report assembly binds when using .NET Core/Standard. I don't know if this is a bug or a feature waiting to be implemented. However, the Fusion log is really useful so I hope we will be able to continue using it in the future.Manes
What kind of project do you run this library from? .NET Core console app, classic ASP.NET web app, classic test project, .NET Core test project, …?Muhammad
M
17

In addition to having a .NET Standard library you also have an application (like a console application) or perhaps a test project. The platform for the application determines what specific assembly referenced by your .NET Standard library to load.

So your library references System.Security.Cryptography.Algorithms 4.3.0 however the actual version of the assembly to load for your platform may be 4.1.0 (that is the version you get on .NET Framework 4.6.1).

So you need to inform your application to redirect the desired version (4.3.0) to the actual version for your runtime (4.1.0). You can do that in the app.config file. Remember that this file is used by the application and not the library. Adding an app.config file to your library will not make a difference.

I tried to create a small project like the one you describe that in addition to a .NET Standard 1.4 library that references System.Security.Cryptography.Algorithms 4.3.0 has a NET Framework 4.62 console application and I had to include an app.config file with the following contents for this to work:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
  </startup>

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.1.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Security.Cryptography.Algorithms" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.1.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Anecdotally, this seems to be less of a problem if you switch to .NET Standard 2.0.

Manes answered 5/9, 2017 at 10:52 Comment(1)
@Carlos28: To fix your problem you need to ensure that System.Security.Cryptography.Algorithms.dll is in your bin folder. If the assembly version of it is not the same as 4.3.0 you have to create a binding redirect to redirect 4.3.0 to the version in your bin folder. You may have to use redirects that are different compared to those I have provided in my answer. It depends on the platform of your application.Manes
M
9

If this library is to be used in "classic" projects, you may need to activate automatic binding redirect generation in the consuming projects / libraries (unit test projects count as library here). This can be done by adding these to properties to the csproj file of the consuming(!) project:

<PropertyGroup>
  <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
  <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>

See the related "Issues with .NET Standard 2.0 with .NET Framework & NuGet" announcement post for more details and options.

Muhammad answered 5/9, 2017 at 15:16 Comment(1)
That worked for me (Net 4.8 referencing Net Std 2.0). I have also added <RestoreProjectStyle>PackageReference</RestoreProjectStyle> into the same property group.Ebullition
R
0

Solutions that I have found:

  • Update library from .NET Standard 1.4 to 2.0 then it works with:

  • System.Security.Cryptography.Algorithms v=4.3.0

  • System.Security.Cryptography.Primitives v=4.3.0

  • According to this topic it should work on .NET Standard 1.3 and:

  • System.Security.Cryptography.Algorithms v=4.2.0

  • System.Security.Cryptography.Primitives v=4.0.0

For .Net Standard 1.4 solution proposed by Martin Liversage is good option.

Robison answered 5/9, 2017 at 13:45 Comment(0)
P
0

In my case, I just added the NuGet package to the main Net application as well (despite I use the crypto things in separate NetStandard 2.0 class lib, not in the main app codebase) and that solved the issue.

Besides, my main Net app is Net.Framework 4.6.1

Pamela answered 1/10, 2020 at 10:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.