internal static byte[] Decode (CookieProtection cookieProtection, string data, Purpose purpose)
        {
            byte[] buf = HttpServerUtility.UrlTokenDecode(data);
            if (AspNetCryptoServiceProvider.Instance.IsDefaultProvider) {
                // If we're configured to go through the new crypto routines, do so.
                ICryptoService cryptoService = AspNetCryptoServiceProvider.Instance.GetCryptoService(purpose);
                return cryptoService.Unprotect(buf);
            }

#pragma warning disable 618 // calling obsolete methods
            // Otherwise fall back to using MachineKeySection.
            if (buf == null || cookieProtection == CookieProtection.None)
                return buf;
            if (cookieProtection == CookieProtection.All || cookieProtection == CookieProtection.Encryption)
            {
                buf = MachineKeySection.EncryptOrDecryptData (false, buf, null, 0, buf.Length);
                if (buf == null)
                    return null;
            }

            if (cookieProtection == CookieProtection.All || cookieProtection == CookieProtection.Validation)
                return MachineKeySection.GetUnHashedData(buf);
            return buf;
#pragma warning restore 618 // calling obsolete methods
        }
Exemple #2
0
 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));
        }
        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);
        }
        internal static string Encode (CookieProtection cookieProtection, byte [] buf, Purpose purpose)
        {
            if (AspNetCryptoServiceProvider.Instance.IsDefaultProvider) {
                // If we're configured to go through the new crypto routines, do so.
                ICryptoService cryptoService = AspNetCryptoServiceProvider.Instance.GetCryptoService(purpose);
                return HttpServerUtility.UrlTokenEncode(cryptoService.Protect(buf));
            }

#pragma warning disable 618 // calling obsolete methods
            // Otherwise fall back to using MachineKeySection.
            int count = buf.Length;
            if (cookieProtection == CookieProtection.All || cookieProtection == CookieProtection.Validation)
            {
                byte[] bMac = MachineKeySection.HashData (buf, null, 0, count);

                if (bMac == null)
                    return null;
                if (buf.Length >= count + bMac.Length)
                {
                    Buffer.BlockCopy (bMac, 0, buf, count, bMac.Length);
                }
                else
                {
                    byte[] bTemp = buf;
                    buf = new byte[count + bMac.Length];
                    Buffer.BlockCopy (bTemp, 0, buf, 0, count);
                    Buffer.BlockCopy (bMac, 0, buf, count, bMac.Length);
                }
                count += bMac.Length;
            }

            if (cookieProtection == CookieProtection.All || cookieProtection == CookieProtection.Encryption)
            {
                buf = MachineKeySection.EncryptOrDecryptData (true, buf, null, 0, count);
                count = buf.Length;
            }
            if (count < buf.Length)
            {
                byte[] bTemp = buf;
                buf = new byte[count];
                Buffer.BlockCopy (bTemp, 0, buf, 0, count);
            }
#pragma warning restore 618 // calling obsolete methods

            return HttpServerUtility.UrlTokenEncode(buf);
        }
        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);
            }
        }
Exemple #9
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));
            }
        }
 private DataProtectorCryptoService GetDataProtectorCryptoService(Purpose purpose) {
     // just return the ICryptoService directly
     return new DataProtectorCryptoService(_dataProtectorFactory, purpose);
 }
 private DataProtectorCryptoService GetDataProtectorCryptoService(Purpose purpose)
 {
     // just return the ICryptoService directly
     return(new DataProtectorCryptoService(_dataProtectorFactory, purpose));
 }
        private string Serialize(object stateGraph, Purpose purpose) {
            string result = null;

            MemoryStream ms = GetMemoryStream();
            try {
                Serialize(ms, stateGraph);
                ms.SetLength(ms.Position);

                byte[] buffer = ms.GetBuffer();
                int length = (int)ms.Length;

#if !FEATURE_PAL // FEATURE_PAL does not enable cryptography
                // We only support serialization of encrypted or encoded data through our internal Page constructors

                if (AspNetCryptoServiceProvider.Instance.IsDefaultProvider && !_forceLegacyCryptography) {
                    // If we're configured to use the new crypto providers, call into them if encryption or signing (or both) is requested.

                    if (_page != null && (_page.RequiresViewStateEncryptionInternal || _page.EnableViewStateMac)) {
                        Purpose derivedPurpose = purpose.AppendSpecificPurposes(GetSpecificPurposes());
                        ICryptoService cryptoService = AspNetCryptoServiceProvider.Instance.GetCryptoService(derivedPurpose);
                        byte[] protectedData = cryptoService.Protect(ms.ToArray());
                        buffer = protectedData;
                        length = protectedData.Length;
                    }
                }
                else {
                    // Otherwise go through legacy crypto mechanisms
#pragma warning disable 618 // calling obsolete methods
                    if (_page != null && _page.RequiresViewStateEncryptionInternal) {
                        buffer = MachineKeySection.EncryptOrDecryptData(true, buffer, GetMacKeyModifier(), 0, length);
                        length = buffer.Length;
                    }
                    // We need to encode if the page has EnableViewStateMac or we got passed in some mac key string
                    else if ((_page != null && _page.EnableViewStateMac) || _macKeyBytes != null) {
                        buffer = MachineKeySection.GetEncodedData(buffer, GetMacKeyModifier(), 0, ref length);
                    }
#pragma warning restore 618 // calling obsolete methods
                }

#endif // !FEATURE_PAL
                result = Convert.ToBase64String(buffer, 0, length);
            }
            finally {
                ReleaseMemoryStream(ms);
            }
            return result;
        }
        private object Deserialize(string inputString, Purpose purpose) {
            if (String.IsNullOrEmpty(inputString)) {
                throw new ArgumentNullException("inputString");
            }

            byte[] inputBytes = Convert.FromBase64String(inputString);
            int length = inputBytes.Length;

#if !FEATURE_PAL // FEATURE_PAL does not enable cryptography
            try {
                if (AspNetCryptoServiceProvider.Instance.IsDefaultProvider && !_forceLegacyCryptography) {
                    // If we're configured to use the new crypto providers, call into them if encryption or signing (or both) is requested.

                    if (_page != null && (_page.ContainsEncryptedViewState || _page.EnableViewStateMac)) {
                        Purpose derivedPurpose = purpose.AppendSpecificPurposes(GetSpecificPurposes());
                        ICryptoService cryptoService = AspNetCryptoServiceProvider.Instance.GetCryptoService(derivedPurpose);
                        byte[] clearData = cryptoService.Unprotect(inputBytes);
                        inputBytes = clearData;
                        length = clearData.Length;
                    }
                }
                else {
                    // Otherwise go through legacy crypto mechanisms
#pragma warning disable 618 // calling obsolete methods
                    if (_page != null && _page.ContainsEncryptedViewState) {
                        inputBytes = MachineKeySection.EncryptOrDecryptData(false, inputBytes, GetMacKeyModifier(), 0, length);
                        length = inputBytes.Length;
                    }
                    // We need to decode if the page has EnableViewStateMac or we got passed in some mac key string
                    else if ((_page != null && _page.EnableViewStateMac) || _macKeyBytes != null) {
                        inputBytes = MachineKeySection.GetDecodedData(inputBytes, GetMacKeyModifier(), 0, length, ref length);
                    }
#pragma warning restore 618 // calling obsolete methods
                }
            }
            catch {
                // MSRC 10405: Don't propagate inner exceptions, as they may contain sensitive cryptographic information.
                PerfCounters.IncrementCounter(AppPerfCounter.VIEWSTATE_MAC_FAIL);
                ViewStateException.ThrowMacValidationError(null, inputString);
            }
#endif // !FEATURE_PAL
            object result = null;
            MemoryStream objectStream = GetMemoryStream();
            try {
                objectStream.Write(inputBytes, 0, length);
                objectStream.Position = 0;
                result = Deserialize(objectStream);
            }
            finally {
                ReleaseMemoryStream(objectStream);
            }
            return result;
        }
 string IStateFormatter2.Serialize(object state, Purpose purpose) {
     return Serialize(state, purpose);
 }
 object IStateFormatter2.Deserialize(string serializedState, Purpose purpose) {
     return Deserialize(serializedState, purpose);
 }
 internal static object DeserializeWithAssert(IStateFormatter2 formatter, string serializedState, Purpose purpose) {
     return formatter.Deserialize(serializedState, purpose);
 }
 internal static string SerializeWithAssert(IStateFormatter2 formatter, object stateGraph, Purpose purpose) {
     return formatter.Serialize(stateGraph, purpose);
 }
Exemple #18
0
 public DataProtectorCryptoService(IDataProtectorFactory dataProtectorFactory, Purpose purpose)
 {
     _dataProtectorFactory = dataProtectorFactory;
     _purpose = 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 ConfigUtil.MakeConfigurationErrorsException(
                                  message: SR.GetString(errorResourceString),
                                  configProperty: _machineKeySection.ElementInformation.Properties[configAttributeName]);
                    }
                }
            }

            if (!autoGenerate)
            {
                // at the absolute minimum, we must be configured to autogenerate
                throw ConfigUtil.MakeConfigurationErrorsException(
                          message: SR.GetString(errorResourceString),
                          configProperty: _machineKeySection.ElementInformation.Properties[configAttributeName]);
            }

            // 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));
        }
        // 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 ConfigUtil.MakeConfigurationErrorsException(
                                message: SR.GetString(errorResourceString),
                                configProperty: _machineKeySection.ElementInformation.Properties[configAttributeName]);
                    }
                }
            }

            if (!autoGenerate) {
                // at the absolute minimum, we must be configured to autogenerate
                throw ConfigUtil.MakeConfigurationErrorsException(
                    message: SR.GetString(errorResourceString),
                    configProperty: _machineKeySection.ElementInformation.Properties[configAttributeName]);
            }

            // 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;
 }
 public DataProtector GetDataProtector(Purpose purpose) {
     if (_dataProtectorFactory == null) {
         _dataProtectorFactory = GetDataProtectorFactory();
     }
     return _dataProtectorFactory(purpose);
 }