public DataProtector GetDataProtector(Purpose purpose) { if (_dataProtectorFactory == null) { _dataProtectorFactory = GetDataProtectorFactory(); } return(_dataProtectorFactory(purpose)); }
private NetFXCryptoService GetNetFXCryptoService(Purpose purpose, CryptoServiceOptions options) { // Extract the encryption and validation keys from the provided Purpose object CryptographicKey encryptionKey = purpose.GetDerivedEncryptionKey(_masterKeyProvider, _keyDerivationFunction); CryptographicKey validationKey = purpose.GetDerivedValidationKey(_masterKeyProvider, _keyDerivationFunction); // and return the ICryptoService // (predictable IV turned on if the caller requested cacheable output) return(new NetFXCryptoService(_cryptoAlgorithmFactory, encryptionKey, validationKey, predictableIV: (options == CryptoServiceOptions.CacheableOutput))); }
public ICryptoService GetCryptoService(Purpose purpose, CryptoServiceOptions options = CryptoServiceOptions.None) { ICryptoService cryptoService; if (_isDataProtectorEnabled && options == CryptoServiceOptions.None) { // We can only use DataProtector if it's configured and the caller didn't ask for any special behavior like cacheability cryptoService = GetDataProtectorCryptoService(purpose); } else { // Otherwise we fall back to using the <machineKey> algorithms for cryptography cryptoService = GetNetFXCryptoService(purpose, options); } // always homogenize errors returned from the crypto service return(new HomogenizingCryptoServiceWrapper(cryptoService)); }
// 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)); } }
private DataProtectorCryptoService GetDataProtectorCryptoService(Purpose purpose) { // just return the ICryptoService directly return(new DataProtectorCryptoService(_dataProtectorFactory, purpose)); }
// Generates 'cryptographicKey' from either the raw key material specified in config // or from the auto-generated key found in the system registry, optionally performing // subkey derivation. private CryptographicKey GenerateCryptographicKey(string configAttributeName, string configAttributeValue, int autogenKeyOffset, int autogenKeyCount, string errorResourceString) { byte[] keyMaterial = CryptoUtil.HexToBinary(configAttributeValue); // If <machineKey> contained a valid key, just use it verbatim. if (keyMaterial != null && keyMaterial.Length > 0) { return(new CryptographicKey(keyMaterial)); } // Otherwise, we need to generate it. bool autoGenerate = false; bool isolateApps = false; bool isolateByAppId = false; if (configAttributeValue != null) { foreach (string flag in configAttributeValue.Split(',')) { switch (flag) { case "AutoGenerate": autoGenerate = true; break; case "IsolateApps": isolateApps = true; break; case "IsolateByAppId": isolateByAppId = true; break; default: throw new ConfigurationException(configAttributeName + " is null"); } } } if (!autoGenerate) { throw new ConfigurationException(configAttributeName + " is null"); } // The key should be a subset of the auto-generated key (which is a concatenation of several keys) CryptographicKey keyDerivationKey = AutogenKeys.ExtractBits(autogenKeyOffset, autogenKeyCount); List <string> specificPurposes = new List <string>(); if (isolateApps) { // Use the application name to derive a new cryptographic key AddSpecificPurposeString(specificPurposes, AUTOGEN_KEYDERIVATION_ISOLATEAPPS_SPECIFICPURPOSE, ApplicationName); } if (isolateByAppId) { // Use the application ID to derive a new cryptographic key AddSpecificPurposeString(specificPurposes, AUTOGEN_KEYDERIVATION_ISOLATEBYAPPID_SPECIFICPURPOSE, ApplicationId); } // Don't use the auto-gen key directly; derive a new one based on specified parameters. Purpose purpose = new Purpose(AUTOGEN_KEYDERIVATION_PRIMARYPURPOSE, specificPurposes.ToArray()); return(KeyDerivationFunction(keyDerivationKey, purpose)); }
public DataProtectorCryptoService(IDataProtectorFactory dataProtectorFactory, Purpose purpose) { _dataProtectorFactory = dataProtectorFactory; _purpose = purpose; }