コード例 #1
0
 // the only required parameter is 'machineKeySection'; other parameters are just used for unit testing
 internal MachineKeyMasterKeyProvider(MachineKeyConfig machineKeySection, string applicationId = null, string applicationName = null, CryptographicKey autogenKeys = null, KeyDerivationFunction keyDerivationFunction = null)
 {
     _machineKeyConfig      = machineKeySection;
     _applicationId         = applicationId;
     _applicationName       = applicationName;
     _autogenKeys           = autogenKeys;
     _keyDerivationFunction = keyDerivationFunction;
 }
コード例 #2
0
 // 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);
 }
コード例 #3
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)));
        }
コード例 #4
0
 public CryptographicKey GetValidationKey()
 {
     if (_validationKey == null)
     {
         _validationKey = GenerateCryptographicKey(
             configAttributeName: "validationKey",
             configAttributeValue: _machineKeyConfig.ValidationKey,
             autogenKeyOffset: AUTOGEN_VALIDATION_OFFSET,
             autogenKeyCount: AUTOGEN_VALIDATION_KEYLENGTH,
             errorResourceString: SR.Invalid_validation_key);
     }
     return(_validationKey);
 }
コード例 #5
0
 public CryptographicKey GetEncryptionKey()
 {
     if (_encryptionKey == null)
     {
         _encryptionKey = GenerateCryptographicKey(
             configAttributeName: "decryptionKey",
             configAttributeValue: _machineKeyConfig.DecryptionKey,
             autogenKeyOffset: AUTOGEN_ENCRYPTION_OFFSET,
             autogenKeyCount: AUTOGEN_ENCRYPTION_KEYLENGTH,
             errorResourceString: SR.Invalid_decryption_key);
     }
     return(_encryptionKey);
 }
コード例 #6
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);
        }
コード例 #7
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));
            }
        }
コード例 #8
0
 public NetFXCryptoService(ICryptoAlgorithmFactory cryptoAlgorithmFactory, CryptographicKey encryptionKey, CryptographicKey validationKey, bool predictableIV = false)
 {
     _cryptoAlgorithmFactory = cryptoAlgorithmFactory;
     _encryptionKey          = encryptionKey;
     _validationKey          = validationKey;
     _predictableIV          = predictableIV;
 }
コード例 #9
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));
        }