Skip to content

Instantly share code, notes, and snippets.

@charlesportwoodii
Last active October 4, 2019 09:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save charlesportwoodii/a571e1a3541b708df18881f086e31002 to your computer and use it in GitHub Desktop.
Save charlesportwoodii/a571e1a3541b708df18881f086e31002 to your computer and use it in GitHub Desktop.
PBKDF2 Implementation in C# for Universal Windows Platform (UWP)

PBKDF2

The following gists implement PBKDF2 in C# for Universal Windows Platform (UWP). The class should be portable to Windows 10, Windows 10 Mobile, and WinRT.

Usage

The class will return a hex string using the default parameters. By default the string will be sized to 16 bytes, and will be hashed 100000 times

string password = "my secret password";
string salt = "<salt>"; // Should be sized to 64 bytes for SHA256, and 128 for SHA512
string pbdfk = new PBKDF(password, salt).hash;
System.Diagnostics.Debug.WriteLine(pbkdf); // Output in HEX format

Optionally, the algorithm paramter can be passed to change the default algorithm from Pbkdf2Sha256. The algorithm string may be one of the following

KeyDerivationAlgorithmNames.Pbkdf2Md5 // PBKDF2_MD5
KeyDerivationAlgorithmNames.Pbkdf2Sha1 // PBKDF2_SHA1
KeyDerivationAlgorithmNames.Pbkdf2Sha256 // PBKDF2_SHA256
KeyDerivationAlgorithmNames.Pbkdf2Sha384 // PBKDF2_SHA384
KeyDerivationAlgorithmNames.Pbkdf2Sha512 // PBKDF2_SHA512

Example as shown:

string pbdfk = new PBKDF(password, salt, KeyDerivationAlgorithmNames.Pbkdf2Sha512).hash;

Additionally, the iteration count and target size can be adjusted by providing the next two paramters

// SHA-256 PBKDK2, 150000 iterations, with a 32 bit output size
string pbdfk = new PBKDF(password, salt, KeyDerivationAlgorithmNames.Pbkdf2Sha256, 150000, 32).hash;

As previously mentioned, the result will be returned as a hex string, but can be converted back to an IBuffer using the CryptographicBuffer class.

string pbdfk = new PBKDF(password, salt).hash;
IBuffer keyMaterials = CryptographicBuffer.DecodeFromHexString(hash);
/**
* PBKDF algorithm
*/
class PBKDF
{
/**
* The algorithm to use
* @var string algorithm
*/
private string algorithm = KeyDerivationAlgorithmNames.Pbkdf2Sha256;
/**
* The PBDFK2 hash
* @var string hash
*/
public string hash;
/**
* Generate a PBDFK hash
* @param string password
* @param string salt
* @param string algorithm
* @param uint iterationCountIn
* @param uint target size
*/
public PBKDF(string password, string salt, string algorithm = null, uint iterationCountIn = 100000, uint targetSize = 16)
{
// Use the provide KeyDerivationAlgorithm if provided, otherwise default to PBKDF2-SHA256
if (algorithm == null)
algorithm = this.algorithm;
KeyDerivationAlgorithmProvider provider = KeyDerivationAlgorithmProvider.OpenAlgorithm(algorithm);
// This is our secret password
IBuffer buffSecret = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8);
// Use the provided salt
IBuffer buffSalt = CryptographicBuffer.ConvertStringToBinary(salt, BinaryStringEncoding.Utf8);
// Create the derivation parameters.
KeyDerivationParameters pbkdf2Params = KeyDerivationParameters.BuildForPbkdf2(buffSalt, iterationCountIn);
// Create a key from the secret value.
CryptographicKey keyOriginal = provider.CreateKey(buffSecret);
// Derive a key based on the original key and the derivation parameters.
IBuffer keyDerived = CryptographicEngine.DeriveKeyMaterial(
keyOriginal,
pbkdf2Params,
targetSize
);
// Encode the key to a hexadecimal value (for display)
hash = CryptographicBuffer.EncodeToHexString(keyDerived);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment