// ctor for unit testing
 internal Purpose(string primaryPurpose, string[] specificPurposes, CryptographicKey derivedEncryptionKey, CryptographicKey derivedValidationKey)
 {
     PrimaryPurpose       = primaryPurpose;
     SpecificPurposes     = specificPurposes ?? new string[0];
     DerivedEncryptionKey = derivedEncryptionKey;
     DerivedValidationKey = derivedValidationKey;
     SaveDerivedKeys      = (SpecificPurposes.Length == 0);
 }
        public CryptographicKey GetDerivedValidationKey(IMasterKeyProvider masterKeyProvider, KeyDerivationFunction keyDerivationFunction)
        {
            // has a key already been stored?
            CryptographicKey actualDerivedKey = DerivedValidationKey;

            if (actualDerivedKey == null)
            {
                CryptographicKey masterKey = masterKeyProvider.GetValidationKey();
                actualDerivedKey = keyDerivationFunction(masterKey, this);

                // only save the key back to storage if this Purpose is configured to do so
                if (SaveDerivedKeys)
                {
                    DerivedValidationKey = actualDerivedKey;
                }
            }

            return(actualDerivedKey);
        }
Exemple #3
0
        // Implements the KeyDerivationFunction delegate signature; public entry point to the API.
        public static CryptographicKey DeriveKey(CryptographicKey keyDerivationKey, Purpose purpose)
        {
            // After consultation with the crypto board, we have decided to use HMACSHA512 as the PRF
            // to our KDF. The reason for this is that our PRF is an HMAC, so the total entropy of the
            // PRF is given by MIN(key derivation key length, HMAC block size). It is conceivable that
            // a developer might specify a key greater than 256 bits in length, at which point using
            // a shorter PRF like HMACSHA256 starts discarding entropy. But from the crypto team's
            // perspective it is unreasonable for a developer to supply a key greater than 512 bits,
            // so there's no real harm in us limiting our PRF entropy to 512 bits (HMACSHA512).
            //
            // On 64-bit platforms, HMACSHA512 matches or outperforms HMACSHA256 in our perf testing.
            // On 32-bit platforms, HMACSHA512 is around 1/3 the speed of HMACSHA256. In both cases, we
            // try to cache the derived CryptographicKey wherever we can, so this shouldn't be a
            // bottleneck regardless.

            using (HMACSHA512 hmac = CryptoAlgorithms.CreateHMACSHA512(keyDerivationKey.GetKeyMaterial()))
            {
                byte[] label, context;
                purpose.GetKeyDerivationParameters(out label, out context);

                byte[] derivedKey = DeriveKeyImpl(hmac, label, context, keyDerivationKey.KeyLength);
                return(new CryptographicKey(derivedKey));
            }
        }
 public NetFXCryptoService(ICryptoAlgorithmFactory cryptoAlgorithmFactory, CryptographicKey encryptionKey, CryptographicKey validationKey, bool predictableIV = false)
 {
     _cryptoAlgorithmFactory = cryptoAlgorithmFactory;
     _encryptionKey          = encryptionKey;
     _validationKey          = validationKey;
     _predictableIV          = predictableIV;
 }