/// <summary> /// This is the click handler for the 'RunSample' button. It is responsible for executing the sample code. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void RunSample_Click(object sender, RoutedEventArgs e) { String algName = AlgorithmNames.SelectionBoxItem.ToString(); IBuffer Secret = CryptographicBuffer.ConvertStringToBinary("Master key to derive from", BinaryStringEncoding.Utf8); UInt32 TargetSize = UInt32.Parse(KeySizes.SelectionBoxItem.ToString()); KeyDerivationText.Text = ""; KeyDerivationParameters Params; if (algName.Contains("PBKDF2")) { // Password based key derivation function (PBKDF2). Params = KeyDerivationParameters.BuildForPbkdf2( CryptographicBuffer.GenerateRandom(16), // Salt 10000 // PBKDF2 Iteration Count ); } else if (algName.Contains("SP800_108")) { // SP800_108_CTR_HMAC key derivation function. Params = KeyDerivationParameters.BuildForSP800108( CryptographicBuffer.ConvertStringToBinary("Label", BinaryStringEncoding.Utf8), // Label CryptographicBuffer.DecodeFromHexString("303132333435363738") // Context ); } else if (algName.Contains("SP800_56A")) { Params = KeyDerivationParameters.BuildForSP80056a( CryptographicBuffer.ConvertStringToBinary("AlgorithmId", BinaryStringEncoding.Utf8), CryptographicBuffer.ConvertStringToBinary("VParty", BinaryStringEncoding.Utf8), CryptographicBuffer.ConvertStringToBinary("UParty", BinaryStringEncoding.Utf8), CryptographicBuffer.ConvertStringToBinary("SubPubInfo", BinaryStringEncoding.Utf8), CryptographicBuffer.ConvertStringToBinary("SubPrivInfo", BinaryStringEncoding.Utf8) ); } else { KeyDerivationText.Text += " An invalid algorithm was specified.\n"; return; } // Create a KeyDerivationAlgorithmProvider object for the algorithm specified on input. KeyDerivationAlgorithmProvider Algorithm = KeyDerivationAlgorithmProvider.OpenAlgorithm(algName); KeyDerivationText.Text += "*** Sample Kdf Algorithm: " + Algorithm.AlgorithmName + "\n"; KeyDerivationText.Text += " Secrect Size: " + Secret.Length + "\n"; KeyDerivationText.Text += " Target Size: " + TargetSize + "\n"; // Create a key. CryptographicKey key = Algorithm.CreateKey(Secret); // Derive a key from the created key. IBuffer derived = CryptographicEngine.DeriveKeyMaterial(key, Params, TargetSize); KeyDerivationText.Text += " Derived " + derived.Length + " bytes\n"; KeyDerivationText.Text += " Derived: " + CryptographicBuffer.EncodeToHexString(derived) + "\n"; }
public void GenerateKey(string password, string salt, out Windows.Storage.Streams.IBuffer keyMaterial, out Windows.Storage.Streams.IBuffer iv) { IBuffer saltBuffer = CryptographicBuffer.ConvertStringToBinary(salt, BinaryStringEncoding.Utf8); KeyDerivationParameters keyParams = KeyDerivationParameters.BuildForSP800108(saltBuffer, GetNonce()); KeyDerivationAlgorithmProvider kdf = KeyDerivationAlgorithmProvider.OpenAlgorithm(Encryptor.Settings.KeyDerivationAlgorithm); IBuffer passwordBuffer = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8); CryptographicKey keyOriginal = kdf.CreateKey(passwordBuffer); int keySize = 256; int ivSize = 128 / 8; uint totalData = (uint)(keySize + ivSize); IBuffer keyDerived = CryptographicEngine.DeriveKeyMaterial(keyOriginal, keyParams, totalData); byte[] keyMaterialBytes = keyDerived.ToArray(); keyMaterial = WindowsRuntimeBuffer.Create(keyMaterialBytes, 0, keySize, keySize); iv = WindowsRuntimeBuffer.Create(keyMaterialBytes, keySize, ivSize, ivSize); }
} // VerifySignature() /// <summary> /// Generates the key exchange key and the public part of the ephemeral key /// using specified encoding parameters in the KDF (ECC only). /// </summary> /// <param name="encodingParms"></param> /// <param name="decryptKeyNameAlg"></param> /// <param name="ephemPub"></param> /// <returns>key exchange key blob</returns> public byte[] EcdhGetKeyExchangeKey(byte[] encodingParms, TpmAlgId decryptKeyNameAlg, out EccPoint ephemPub) { var eccParms = (EccParms)PublicParms.parameters; int keyBits = RawEccKey.GetKeyLength(eccParms.curveID); byte[] keyExchangeKey = null; ephemPub = new EccPoint(); // Make a new ephemeral key var prov = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(RawEccKey.GetEccAlg(PublicParms)); var ephKey = prov.CreateKeyPair((uint)keyBits); IBuffer ephPubBuf = ephKey.ExportPublicKey(CryptographicPublicKeyBlobType.BCryptEccFullPublicKey); byte[] ephPub; CryptographicBuffer.CopyToByteArray(ephPubBuf, out ephPub); IBuffer otherPubBuf = Key.ExportPublicKey(CryptographicPublicKeyBlobType.BCryptEccFullPublicKey); byte[] otherPub; CryptographicBuffer.CopyToByteArray(otherPubBuf, out otherPub); byte[] herPubX, herPubY; RawEccKey.KeyInfoFromPublicBlob(otherPub, out herPubX, out herPubY); byte[] myPubX, myPubY; RawEccKey.KeyInfoFromPublicBlob(ephPub, out myPubX, out myPubY); byte[] otherInfo = Globs.Concatenate(new[] { encodingParms, myPubX, herPubX }); // The TPM uses the following number of bytes from the KDF int bytesNeeded = CryptoLib.DigestSize(decryptKeyNameAlg); keyExchangeKey = new byte[bytesNeeded]; for (int pos = 0, count = 1, bytesToCopy = 0; pos < bytesNeeded; ++count, pos += bytesToCopy) { byte[] secretPrepend = Marshaller.GetTpmRepresentation((UInt32)count); string algName; KeyDerivationParameters deriveParams; switch (decryptKeyNameAlg) { case TpmAlgId.Kdf1Sp800108: algName = KeyDerivationAlgorithmNames.Sp800108CtrHmacSha256; deriveParams = KeyDerivationParameters.BuildForSP800108(CryptographicBuffer.CreateFromByteArray(secretPrepend), CryptographicBuffer.CreateFromByteArray(otherInfo)); break; case TpmAlgId.Kdf1Sp80056a: algName = KeyDerivationAlgorithmNames.Sp80056aConcatSha256; deriveParams = KeyDerivationParameters.BuildForSP80056a(CryptographicBuffer.ConvertStringToBinary(algName, BinaryStringEncoding.Utf8), CryptographicBuffer.ConvertStringToBinary("TPM", BinaryStringEncoding.Utf8), CryptographicBuffer.CreateFromByteArray(secretPrepend), CryptographicBuffer.ConvertStringToBinary("", BinaryStringEncoding.Utf8), CryptographicBuffer.CreateFromByteArray(otherInfo)); break; case TpmAlgId.Kdf2: algName = KeyDerivationAlgorithmNames.Pbkdf2Sha256; deriveParams = KeyDerivationParameters.BuildForPbkdf2(CryptographicBuffer.CreateFromByteArray(secretPrepend), 1000); break; default: Globs.Throw <ArgumentException>("wrong KDF name"); return(null); } KeyDerivationAlgorithmProvider deriveProv = KeyDerivationAlgorithmProvider.OpenAlgorithm(algName); IBuffer keyMaterial = CryptographicEngine.DeriveKeyMaterial(Key, deriveParams, (uint)keyBits); byte[] fragment; CryptographicBuffer.CopyToByteArray(keyMaterial, out fragment); bytesToCopy = Math.Min(bytesNeeded - pos, fragment.Length); Array.Copy(fragment, 0, keyExchangeKey, pos, bytesToCopy); } ephemPub = new EccPoint(myPubX, myPubY); return(keyExchangeKey); }