Giter Site home page Giter Site logo

andreimilto / hkdf.standard Goto Github PK

View Code? Open in Web Editor NEW
4.0 2.0 0.0 1.51 MB

Fast, cross-platform, RFC-compliant implementation of HMAC-based Extract-and-Expand Key Derivation Function (HKDF) in .NET Standard

License: MIT License

C# 100.00%
hkdf kdf hmac csharp key-derivation rfc5869 uwp mono net-5 net-framework

hkdf.standard's Introduction

Get NuGet Package

AppVeyor Build AppVeyor Tests GitHub License

HKDF.Standard

.NET Standard implementation of HKDF (HMAC-based Key Derivation Function).

Features

Getting Started

Install the NuGet package HKDF.Standard.

Use the methods of the Hkdf class to perform extraction, expansion and key derivation:

using HkdfStandard;
using System.Security.Cryptography;

// Input values:
byte[] inputKeyMaterial = ...;
byte[] salt = ...;
byte[] info = ...;
int outputLength = ...;

// Results:
byte[] pseudoRandomKey;
byte[] outputKeyMaterial;

// Perform the Extract stage of HKDF with or without the salt:
pseudoRandomKey = Hkdf.Extract(HashAlgorithmName.SHA256, inputKeyMaterial, salt);
pseudoRandomKey = Hkdf.Extract(HashAlgorithmName.SHA256, inputKeyMaterial);

// Perform the Expand stage of HKDF with or without the context information:
outputKeyMaterial = Hkdf.Expand(HashAlgorithmName.SHA256, pseudoRandomKey, outputLength, info);
outputKeyMaterial = Hkdf.Expand(HashAlgorithmName.SHA256, pseudoRandomKey, outputLength);

// Perform the entire HKDF cycle in one go (Extract + Expand)
// optionally using the salt and/or the context information:
outputKeyMaterial = Hkdf.DeriveKey(HashAlgorithmName.SHA256, inputKeyMaterial, outputLength, salt, info);
outputKeyMaterial = Hkdf.DeriveKey(HashAlgorithmName.SHA256, inputKeyMaterial, outputLength, salt);
outputKeyMaterial = Hkdf.DeriveKey(HashAlgorithmName.SHA256, inputKeyMaterial, outputLength, info: info);
outputKeyMaterial = Hkdf.DeriveKey(HashAlgorithmName.SHA256, inputKeyMaterial, outputLength);

For information about:

Performance

Based on the results of key derivation benchmark, HKDF.Standard is:

  • 2.7 - 7.4 times faster than NSec
  • 1.4 - 5.8 times faster than Bouncy Castle
  • on par with .NET 5 – perfomance difference does not exceed ±10%

Chart: derivation of 128-bit key Chart: derivation of 4096-bit key

256-bit input key material, 256-bit salt, 256-bit context information

Windows 10 Pro x64, .NET 5.0, AMD Ryzen 7 Pro 1700X, single thread, Portable.BouncyCastle v1.9.0, NSec v20.2.0

The benchmark source code is available at src/HkdfStandard.Benchmark

Migration to and from .NET's HKDF

  • Methods in the HKDF.Standard library have the same signatures as in the .NET's HKDF class, which makes it is simple to migrate from one HKDF implementation to the other.
  • Microsoft's implementation of HKDF will be available only in .NET 5 and onwards. Consider using HKDF.Standard if your project targets one of the older frameworks. If later you decide to upgrade the project to .NET 5 or higher, it will be relatively easy to swap the implementation of HKDF with the Microsoft's, if necessary.

Using HKDF.Standard with ECDiffieHellman

HKDF is commonly used in conjunction with Diffie-Hellman (finite field or elliptic curve), where the Diffie-Hellman value (shared secret) is passed through HKDF to derive one or more shared keys.

Unfortunately, this scenario cannot be implemented straightforward with the ECDiffieHellman class because it doesn't allow the export of raw shared secret. However, there is a method ECDiffieHellman.DeriveKeyFromHmac that returns the value of shared secret that was passed through HMAC — this is the same transformation that the input key material undergoes when being passed through the HKDF's Extract stage. Therefore, the workaround is to skip the Extract stage of HKDF and substitute it with ECDiffieHellman's additional HMAC operation:

using HkdfStandard;
using System.Security.Cryptography;

byte[] salt = ...;
byte[] info = ...;
int outputLength = ...;

// My instance of ECDH, contains a new randomly generated key pair:
using var myEcdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256);

// Other party's instance of ECDH, contains a new randomly generated key pair:
using var otherEcdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256);

// Derive the shared ECDH secret and pass it through HMAC along with the salt (as HMAC's message and key respectively).
// This is equivalent to deriving a raw shared secret and running it through the HKDF Extract, which gives a shared pseudorandom key:
byte[] pseudoRandomKey = myEcdh.DeriveKeyFromHmac(otherEcdh.PublicKey, HashAlgorithmName.SHA256, salt);

// Perform the Expand stage of HKDF as usual:
byte[] outputKeyMaterial = Hkdf.Expand(HashAlgorithmName.SHA256, pseudoRandomKey, outputLength, info);

Functionality

byte[] Methods

  • byte[] Extract(HashAlgorithmName hashAlgorithmName, byte[] ikm, byte[]? salt = null);

    Extracts a pseudorandom key from the input key material.

  • byte[] Expand(HashAlgorithmName hashAlgorithmName, byte[] prk, int outputLength, byte[]? info = null);

    Expands the pseudorandom key into an output keying material.

  • byte[] DeriveKey(HashAlgorithmName hashAlgorithmName, byte[] ikm, int outputLength, byte[]? salt = null, byte[]? info = null);

    Derives an output keying material from the input key material (performs extraction and expansion) in one go.

Span<byte> Methods

  • int Extract(HashAlgorithmName hashAlgorithmName, ReadOnlySpan<byte> ikm, ReadOnlySpan<byte> salt, Span<byte> prk);

    Extracts a pseudorandom key from the input key material.

  • void Expand(HashAlgorithmName hashAlgorithmName, ReadOnlySpan<byte> prk, Span<byte> output, ReadOnlySpan<byte> info);

    Expands the pseudorandom key into an output keying material.

  • void DeriveKey(HashAlgorithmName hashAlgorithmName, ReadOnlySpan<byte> ikm, Span<byte> output, ReadOnlySpan<byte> salt, ReadOnlySpan<byte> info);

    Derives an output keying material from the input key material (performs extraction and expansion) in one go.

Platform Support

byte[] methods are available on the platforms that support .NET Standard 1.3:

  • .NET 5 and higher
  • .NET Core 1.0 and higher
  • .NET Framework 4.6 and higher
  • Mono 4.6 and higher
  • Blazor WebAssembly 3.2.0 and higher, except for 5.x.x and 6.x.x, support was resumed in 7.0.0 (for SHA-family only, MD5 - unsupported)
  • Xamarin.iOS 10.0 and higher
  • Xamarin.Mac 3.0 and higher
  • Xamarin.Android 7.0 and higher
  • Unity 2018.1 and higher
  • UWP 10.0 and higher

Span<byte> methods are available on the platforms that support .NET Standard 2.1:

  • .NET 5 and higher
  • .NET Core 3.0 and higher
  • Mono 6.4 and higher
  • Blazor WebAssembly 3.2.0 and higher, except for 5.x.x and 6.x.x, support was resumed in 7.0.0 (for SHA-family only, MD5 - unsupported)
  • Xamarin.iOS 12.16 and higher
  • Xamarin.Mac 5.16 and higher
  • Xamarin.Android 10.0 and higher
  • Unity 2021.2 and higher
  • UWP - currently not supported (expected in the future)

hkdf.standard's People

Contributors

andreimilto avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.