示例#1
0
 public DataProtector GetDataProtector(Purpose purpose)
 {
     if (_dataProtectorFactory == null)
     {
         _dataProtectorFactory = GetDataProtectorFactory();
     }
     return(_dataProtectorFactory(purpose));
 }
示例#2
0
        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)));
        }
示例#3
0
        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));
        }
示例#4
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));
            }
        }
示例#5
0
 private DataProtectorCryptoService GetDataProtectorCryptoService(Purpose purpose)
 {
     // just return the ICryptoService directly
     return(new DataProtectorCryptoService(_dataProtectorFactory, purpose));
 }
示例#6
0
        // 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));
        }
示例#7
0
 public DataProtectorCryptoService(IDataProtectorFactory dataProtectorFactory, Purpose purpose)
 {
     _dataProtectorFactory = dataProtectorFactory;
     _purpose = purpose;
 }