HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

HKDF Implementation in C#

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
hkdfimplementationstackoverflow

Problem

Based on my prior question about HKDF here https://crypto.stackexchange.com/questions/43933/use-of-pbkdf2-when-no-access-to-hkdf and the responses I received I decided to go ahead an implement HKDF based on the rfc5869 spec https://www.rfc-editor.org/rfc/rfc5869 since HKDF wasn't available to me in the .net framework or from a trusted source. I have tested it against the three tests listed in the spec and provided the xUnit code below my HKDF source code. Three tests doesn't seem like much to me though, so I'd value your review and comments.

Updated on 4/13/20 to swap the params of the Extract method which was a bug in the posted code pointed out by Anonymous. It's unclear how that got transposed given that even the code comments show the params in the correct order, and the unit tests call the method in the correct order and had passed at one time. So I'm baffled. Anyway, I appreciate the mistake being pointed out in the posted code and have fixed it below. Specifically the method is corrected to be

public static byte[] Extract(byte[] salt, byte[] inputKeyMaterial)

rather than
public static byte[] Extract(byte[] inputKeyMaterial, byte[] salt).

```
using System;
using System.Security.Cryptography;

namespace App.Security {

///
/// This class implements rfc5869 HMAC-based Extract-and-Expand Key Derivation Function
/// (HKDF) using HMACSHA256.
/// Reference: https://www.rfc-editor.org/rfc/rfc5869
///
public class HKDF {

///
/// Returns a 32 byte psuedorandom number that can be used with the Expand method if
/// a cryptographically secure pseudorandom number is not already available.
///
/// (Optional, but you should use it) Non-secret random value.
/// If less than 64 bytes it is padded with zeros. Can be reused but output is
/// stronger if not reused. (And of course output is much stronger with salt than
/// without it)
/// Material that is

Solution

Just a note but I think you have the parameters backwards in GetBytes:

byte[] key = Extract(salt, inputKeyMaterial);


Based on your implementation of:

byte[] Extract(byte[] inputKeyMaterial, byte[] salt)

Code Snippets

byte[] key = Extract(salt, inputKeyMaterial);
byte[] Extract(byte[] inputKeyMaterial, byte[] salt)

Context

StackExchange Code Review Q#155613, answer score: 4

Revisions (0)

No revisions yet.