kenkendk / FasterHashing

Wrapper library for using native hashing libraries on Windows, Linux and OSX
MIT License
3 stars 4 forks source link
csharp dotnet hashing md5 sha1 sha256 sha384 sha512

FasterHashing

Nuget count License Issues open Codacy Badge

FasterHashing is a wrapper library for using native hashing libraries on Windows, Linux and OSX.

This library addresses a limitation in the current .Net standard profile where HashAlgorithm.Create() always returns the managed versions of the algorithm, even if faster versions exist on the system.

The problem with HashAlgorithm.Create() has been fixed with the .Net Core 2 profile, so if you are using that, you will not benefit from this library. Unfortunately, the implementation for .Net Core 2 relies on a Platform Abstraction Layer, which is a glue library that links into the system libraries. This glue library needs to be complied for the target platform, making it difficult to deploy this with platform independent projects (i.e. using only managed code).

For this reason FasterHashing contains only managed code. If you are using the .Net standard profile (v4.5+) you can simply add this library to your project, change the call from HashAlgorithm.Create("SHA256") to FasterHash.Create("SHA256") and obtain speedups on all supported platforms while falling back to the managed implementation if none are found.

Installation

The FasterHashing NuGet package is the recommended way of installing FasterHashing:

PM> Install-Package FasterHashing

Supported libraries

These libraries are probed for at runtime in this order

Example

The returned item from FasterHash.Create() is a normal HashAlgorithm object, so you can easily replace existing code that uses such an instance.

using FasterHashing;

public static void Main(string[] args) 
{
  using(var sha256 = FasterHash.Create("SHA256"))
    Console.WriteLine(Convert.ToBase64(sha256.ComputeHash(new byte[] { 0, 1, 2, 3 }));
}

Advanced usage

If you want to control which of the library is loaded, you can use some of the utility methods on the static FasterHash class:

using FasterHashing;

public static void Main(string[] args) 
{
  Console.WriteLine("Optimal implementation is: {0}", FasterHash.PreferedImplementation);
  Console.WriteLine("Is Apple Common Crypto Supported: {0}", 
    FasterHash.SupportsImplementation(HashImplementation.AppleCommonCrypto));

  // Manually choose OpenSSL 1.0 version:
  using(var sha256 = FasterHash.Create("SHA256", HashImplementation.OpenSSL10))
  { }

  // Set which version to use:
  FasterHash.PreferedImplementation = HashImplementation.CNG;

  // Or run a benchmark to get the fastest:
  FasterHash.SetDefaultImplementationToFastest();
}

Configure with OpenSSL

FasterHashing will automatically detect various names for OpenSSL, such as libssl.so, libssl.so.1.0.0. It will also detect the libeay32.dll and libcrypto-1.1.dll names on Windows.

If this detection fails for some reason, there are two ways to fix it:

  1. Make a symlink in /lib/libssl.so that points to the fully versioned filename.
  2. Use an assembly config file that remaps to the correct filename.

Option (1) is the simplest, but may require root access.

Option (2) only requires that you add a separate file to the folder where FasterHashing.dll is located, and put in the correct filename. You can probably copy the example assembly config file directly into the target folder.

On Windows, option (2) does not work, but you can optionally drop in the .dll file into the same folder where the main executable is, and rename it to libssl.dll and it will be loaded.