Exemple #1
0
    /// <summary>
    /// Imports the <see cref="ManagedAuthenticatedEncryptorDescriptor"/> from serialized XML.
    /// </summary>
    public IAuthenticatedEncryptorDescriptor ImportFromXml(XElement element)
    {
        if (element == null)
        {
            throw new ArgumentNullException(nameof(element));
        }

        // <descriptor>
        //   <!-- managed implementations -->
        //   <encryption algorithm="..." keyLength="..." />
        //   <validation algorithm="..." />
        //   <masterKey>...</masterKey>
        // </descriptor>

        var configuration = new ManagedAuthenticatedEncryptorConfiguration();

        var encryptionElement = element.Element("encryption") !;

        configuration.EncryptionAlgorithmType    = FriendlyNameToType((string)encryptionElement.Attribute("algorithm") !);
        configuration.EncryptionAlgorithmKeySize = (int)encryptionElement.Attribute("keyLength") !;

        var validationElement = element.Element("validation") !;

        configuration.ValidationAlgorithmType = FriendlyNameToType((string)validationElement.Attribute("algorithm") !);

        Secret masterKey = ((string)element.Element("masterKey") !).ToSecret();

        return(new ManagedAuthenticatedEncryptorDescriptor(configuration, masterKey));
    }
        public void ResolvePolicy_ManagedEncryption_WithExplicitSettings()
        {
            IServiceCollection serviceCollection = new ServiceCollection();

            RunTestWithRegValues(serviceCollection, new Dictionary <string, object>()
            {
                ["EncryptionType"]             = "managed",
                ["EncryptionAlgorithmType"]    = typeof(TripleDES).AssemblyQualifiedName,
                ["EncryptionAlgorithmKeySize"] = 2048,
                ["ValidationAlgorithmType"]    = typeof(HMACMD5).AssemblyQualifiedName
            });

            var services = serviceCollection.BuildServiceProvider();
            var expectedConfiguration = new ManagedAuthenticatedEncryptorConfiguration(new ManagedAuthenticatedEncryptionOptions()
            {
                EncryptionAlgorithmType    = typeof(TripleDES),
                EncryptionAlgorithmKeySize = 2048,
                ValidationAlgorithmType    = typeof(HMACMD5)
            });
            var actualConfiguration = (ManagedAuthenticatedEncryptorConfiguration)services.GetService <IAuthenticatedEncryptorConfiguration>();

            Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmType, actualConfiguration.Options.EncryptionAlgorithmType);
            Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmKeySize, actualConfiguration.Options.EncryptionAlgorithmKeySize);
            Assert.Equal(expectedConfiguration.Options.ValidationAlgorithmType, actualConfiguration.Options.ValidationAlgorithmType);
        }
    internal IAuthenticatedEncryptor?CreateAuthenticatedEncryptorInstance(
        ISecret secret,
        AuthenticatedEncryptorConfiguration?authenticatedConfiguration)
    {
        if (authenticatedConfiguration == null)
        {
            return(null);
        }

        if (IsGcmAlgorithm(authenticatedConfiguration.EncryptionAlgorithm))
        {
#if NETCOREAPP
            return(new AesGcmAuthenticatedEncryptor(secret, GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm) / 8));
#else
            // GCM requires CNG, and CNG is only supported on Windows.
            if (!OSVersionUtil.IsWindows())
            {
                throw new PlatformNotSupportedException(Resources.Platform_WindowsRequiredForGcm);
            }

            Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));

            var configuration = new CngGcmAuthenticatedEncryptorConfiguration()
            {
                EncryptionAlgorithm        = GetBCryptAlgorithmNameFromEncryptionAlgorithm(authenticatedConfiguration.EncryptionAlgorithm),
                EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm)
            };

            return(new CngGcmAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration));
#endif
        }
        else
        {
            if (OSVersionUtil.IsWindows())
            {
                Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
                // CNG preferred over managed implementations if running on Windows
                var configuration = new CngCbcAuthenticatedEncryptorConfiguration()
                {
                    EncryptionAlgorithm        = GetBCryptAlgorithmNameFromEncryptionAlgorithm(authenticatedConfiguration.EncryptionAlgorithm),
                    EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm),
                    HashAlgorithm = GetBCryptAlgorithmNameFromValidationAlgorithm(authenticatedConfiguration.ValidationAlgorithm)
                };

                return(new CngCbcAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration));
            }
            else
            {
                // Use managed implementations as a fallback
                var configuration = new ManagedAuthenticatedEncryptorConfiguration()
                {
                    EncryptionAlgorithmType    = GetManagedTypeFromEncryptionAlgorithm(authenticatedConfiguration.EncryptionAlgorithm),
                    EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm),
                    ValidationAlgorithmType    = GetManagedTypeFromValidationAlgorithm(authenticatedConfiguration.ValidationAlgorithm)
                };

                return(new ManagedAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration));
            }
        }
    }
        private Func <SymmetricAlgorithm> GetSymmetricBlockCipherAlgorithmFactory(ManagedAuthenticatedEncryptorConfiguration configuration)
        {
            // basic argument checking
            if (configuration.EncryptionAlgorithmType == null)
            {
                throw Error.Common_PropertyCannotBeNullOrEmpty(nameof(configuration.EncryptionAlgorithmType));
            }
            typeof(SymmetricAlgorithm).AssertIsAssignableFrom(configuration.EncryptionAlgorithmType);
            if (configuration.EncryptionAlgorithmKeySize < 0)
            {
                throw Error.Common_PropertyMustBeNonNegative(nameof(configuration.EncryptionAlgorithmKeySize));
            }

            _logger.UsingManagedSymmetricAlgorithm(configuration.EncryptionAlgorithmType.FullName !);

            if (configuration.EncryptionAlgorithmType == typeof(Aes))
            {
                Func <Aes>?factory = null;
                if (OSVersionUtil.IsWindows())
                {
                    // If we're on desktop CLR and running on Windows, use the FIPS-compliant implementation.
                    factory = () => new AesCryptoServiceProvider();
                }

                return(factory ?? Aes.Create);
            }
            else
            {
                return(AlgorithmActivator.CreateFactory <SymmetricAlgorithm>(configuration.EncryptionAlgorithmType));
            }
        }
        public void ResolvePolicy_ManagedEncryption_WithExplicitSettings()
        {
            // Arrange
            var registryEntries = new Dictionary <string, object>()
            {
                ["EncryptionType"]             = "managed",
                ["EncryptionAlgorithmType"]    = typeof(TripleDES).AssemblyQualifiedName,
                ["EncryptionAlgorithmKeySize"] = 2048,
                ["ValidationAlgorithmType"]    = typeof(HMACSHA1).AssemblyQualifiedName
            };
            var expectedConfiguration = new ManagedAuthenticatedEncryptorConfiguration()
            {
                EncryptionAlgorithmType    = typeof(TripleDES),
                EncryptionAlgorithmKeySize = 2048,
                ValidationAlgorithmType    = typeof(HMACSHA1)
            };

            // Act
            var context = RunTestWithRegValues(registryEntries);

            // Assert
            var actualConfiguration = (ManagedAuthenticatedEncryptorConfiguration)context.EncryptorConfiguration;

            Assert.Equal(expectedConfiguration.EncryptionAlgorithmType, actualConfiguration.EncryptionAlgorithmType);
            Assert.Equal(expectedConfiguration.EncryptionAlgorithmKeySize, actualConfiguration.EncryptionAlgorithmKeySize);
            Assert.Equal(expectedConfiguration.ValidationAlgorithmType, actualConfiguration.ValidationAlgorithmType);
        }
    public void CreateNewDescriptor_PropagatesOptions()
    {
        // Arrange
        var configuration = new ManagedAuthenticatedEncryptorConfiguration();

        // Act
        var descriptor = (ManagedAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor();

        // Assert
        Assert.Equal(configuration, descriptor.Configuration);
    }
Exemple #7
0
        internal IAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(
            ISecret secret,
            AuthenticatedEncryptorConfiguration authenticatedConfiguration)
        {
            if (authenticatedConfiguration == null)
            {
                return(null);
            }

            if (IsGcmAlgorithm(authenticatedConfiguration.EncryptionAlgorithm))
            {
                // GCM requires CNG, and CNG is only supported on Windows.
                if (!OSVersionUtil.IsWindows())
                {
                    throw new PlatformNotSupportedException("GCM algorithms require the Windows platform.");
                }

                var configuration = new CngGcmAuthenticatedEncryptorConfiguration()
                {
                    EncryptionAlgorithm        = GetBCryptAlgorithmNameFromEncryptionAlgorithm(authenticatedConfiguration.EncryptionAlgorithm),
                    EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm)
                };

                return(new CngGcmAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration));
            }
            else
            {
                if (OSVersionUtil.IsWindows())
                {
                    // CNG preferred over managed implementations if running on Windows
                    var configuration = new CngCbcAuthenticatedEncryptorConfiguration()
                    {
                        EncryptionAlgorithm        = GetBCryptAlgorithmNameFromEncryptionAlgorithm(authenticatedConfiguration.EncryptionAlgorithm),
                        EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm),
                        HashAlgorithm = GetBCryptAlgorithmNameFromValidationAlgorithm(authenticatedConfiguration.ValidationAlgorithm)
                    };

                    return(new CngCbcAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration));
                }
                else
                {
                    // Use managed implementations as a fallback
                    var configuration = new ManagedAuthenticatedEncryptorConfiguration()
                    {
                        EncryptionAlgorithmType    = GetManagedTypeFromEncryptionAlgorithm(authenticatedConfiguration.EncryptionAlgorithm),
                        EncryptionAlgorithmKeySize = GetAlgorithmKeySizeInBits(authenticatedConfiguration.EncryptionAlgorithm),
                        ValidationAlgorithmType    = GetManagedTypeFromValidationAlgorithm(authenticatedConfiguration.ValidationAlgorithm)
                    };

                    return(new ManagedAuthenticatedEncryptorFactory(_loggerFactory).CreateAuthenticatedEncryptorInstance(secret, configuration));
                }
            }
        }
    public void CreateNewDescriptor_CreatesUniqueCorrectlySizedMasterKey()
    {
        // Arrange
        var configuration = new ManagedAuthenticatedEncryptorConfiguration();

        // Act
        var masterKey1 = ((ManagedAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey;
        var masterKey2 = ((ManagedAuthenticatedEncryptorDescriptor)configuration.CreateNewDescriptor()).MasterKey;

        // Assert
        SecretAssert.NotEqual(masterKey1, masterKey2);
        SecretAssert.LengthIs(512 /* bits */, masterKey1);
        SecretAssert.LengthIs(512 /* bits */, masterKey2);
    }
    /// <summary>
    /// Initializes a new instance of <see cref="ManagedAuthenticatedEncryptorDescriptor"/>.
    /// </summary>
    /// <param name="configuration">The <see cref="ManagedAuthenticatedEncryptorConfiguration"/>.</param>
    /// <param name="masterKey">The master key.</param>
    public ManagedAuthenticatedEncryptorDescriptor(ManagedAuthenticatedEncryptorConfiguration configuration, ISecret masterKey)
    {
        if (configuration == null)
        {
            throw new ArgumentNullException(nameof(configuration));
        }

        if (masterKey == null)
        {
            throw new ArgumentNullException(nameof(masterKey));
        }

        Configuration = configuration;
        MasterKey     = masterKey;
    }
        internal ManagedAuthenticatedEncryptor CreateAuthenticatedEncryptorInstance(
            ISecret secret,
            ManagedAuthenticatedEncryptorConfiguration configuration)
        {
            if (configuration == null)
            {
                return(null);
            }

            return(new ManagedAuthenticatedEncryptor(
                       keyDerivationKey: new Secret(secret),
                       symmetricAlgorithmFactory: GetSymmetricBlockCipherAlgorithmFactory(configuration),
                       symmetricAlgorithmKeySizeInBytes: configuration.EncryptionAlgorithmKeySize / 8,
                       validationAlgorithmFactory: GetKeyedHashAlgorithmFactory(configuration)));
        }
        public void ResolvePolicy_ManagedEncryption_WithoutExplicitSettings()
        {
            IServiceCollection serviceCollection = new ServiceCollection();

            RunTestWithRegValues(serviceCollection, new Dictionary <string, object>()
            {
                ["EncryptionType"] = "managed"
            });

            var services = serviceCollection.BuildServiceProvider();
            var expectedConfiguration = new ManagedAuthenticatedEncryptorConfiguration(new ManagedAuthenticatedEncryptionOptions());
            var actualConfiguration   = (ManagedAuthenticatedEncryptorConfiguration)services.GetService <IAuthenticatedEncryptorConfiguration>();

            Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmType, actualConfiguration.Options.EncryptionAlgorithmType);
            Assert.Equal(expectedConfiguration.Options.EncryptionAlgorithmKeySize, actualConfiguration.Options.EncryptionAlgorithmKeySize);
            Assert.Equal(expectedConfiguration.Options.ValidationAlgorithmType, actualConfiguration.Options.ValidationAlgorithmType);
        }
        public void CreateEncrptorInstance_ExpectedDescriptorType_ReturnsEncryptor()
        {
            // Arrange
            var descriptor = new ManagedAuthenticatedEncryptorConfiguration().CreateNewDescriptor();
            var key        = new Mock <IKey>();

            key.Setup(k => k.Descriptor).Returns(descriptor);

            var factory = new ManagedAuthenticatedEncryptorFactory(NullLoggerFactory.Instance);

            // Act
            var encryptor = factory.CreateEncryptorInstance(key.Object);

            // Assert
            Assert.NotNull(encryptor);
            Assert.IsType <ManagedAuthenticatedEncryptor>(encryptor);
        }
        public void ResolvePolicy_ManagedEncryption_WithoutExplicitSettings()
        {
            // Arrange
            var registryEntries = new Dictionary <string, object>()
            {
                ["EncryptionType"] = "managed"
            };
            var expectedConfiguration = new ManagedAuthenticatedEncryptorConfiguration();

            // Act
            var context = RunTestWithRegValues(registryEntries);

            // Assert
            var actualConfiguration = (ManagedAuthenticatedEncryptorConfiguration)context.EncryptorConfiguration;

            Assert.Equal(expectedConfiguration.EncryptionAlgorithmType, actualConfiguration.EncryptionAlgorithmType);
            Assert.Equal(expectedConfiguration.EncryptionAlgorithmKeySize, actualConfiguration.EncryptionAlgorithmKeySize);
            Assert.Equal(expectedConfiguration.ValidationAlgorithmType, actualConfiguration.ValidationAlgorithmType);
        }
        private RegistryPolicy?ResolvePolicyCore(RegistryKey?policyRegKey)
        {
            if (policyRegKey == null)
            {
                return(null);
            }

            // Read the encryption options type: CNG-CBC, CNG-GCM, Managed
            AlgorithmConfiguration?configuration = null;

            var encryptionType = (string?)policyRegKey.GetValue("EncryptionType");

            if (String.Equals(encryptionType, "CNG-CBC", StringComparison.OrdinalIgnoreCase))
            {
                configuration = new CngCbcAuthenticatedEncryptorConfiguration();
            }
            else if (String.Equals(encryptionType, "CNG-GCM", StringComparison.OrdinalIgnoreCase))
            {
                configuration = new CngGcmAuthenticatedEncryptorConfiguration();
            }
            else if (String.Equals(encryptionType, "Managed", StringComparison.OrdinalIgnoreCase))
            {
                configuration = new ManagedAuthenticatedEncryptorConfiguration();
            }
            else if (!String.IsNullOrEmpty(encryptionType))
            {
                throw CryptoUtil.Fail("Unrecognized EncryptionType: " + encryptionType);
            }
            if (configuration != null)
            {
                PopulateOptions(configuration, policyRegKey);
            }

            // Read ancillary data

            var defaultKeyLifetime = (int?)policyRegKey.GetValue("DefaultKeyLifetime");

            var keyEscrowSinks = ReadKeyEscrowSinks(policyRegKey).Select(item => _activator.CreateInstance <IKeyEscrowSink>(item));

            return(new RegistryPolicy(configuration, keyEscrowSinks, defaultKeyLifetime));
        }
    private Func <KeyedHashAlgorithm> GetKeyedHashAlgorithmFactory(ManagedAuthenticatedEncryptorConfiguration configuration)
    {
        // basic argument checking
        if (configuration.ValidationAlgorithmType == null)
        {
            throw Error.Common_PropertyCannotBeNullOrEmpty(nameof(configuration.ValidationAlgorithmType));
        }

        _logger.UsingManagedKeyedHashAlgorithm(configuration.ValidationAlgorithmType.FullName !);
        if (configuration.ValidationAlgorithmType == typeof(HMACSHA256))
        {
            return(() => new HMACSHA256());
        }
        else if (configuration.ValidationAlgorithmType == typeof(HMACSHA512))
        {
            return(() => new HMACSHA512());
        }
        else
        {
            return(AlgorithmActivator.CreateFactory <KeyedHashAlgorithm>(configuration.ValidationAlgorithmType));
        }
    }
    private Func <SymmetricAlgorithm> GetSymmetricBlockCipherAlgorithmFactory(ManagedAuthenticatedEncryptorConfiguration configuration)
    {
        // basic argument checking
        if (configuration.EncryptionAlgorithmType == null)
        {
            throw Error.Common_PropertyCannotBeNullOrEmpty(nameof(configuration.EncryptionAlgorithmType));
        }
        typeof(SymmetricAlgorithm).AssertIsAssignableFrom(configuration.EncryptionAlgorithmType);
        if (configuration.EncryptionAlgorithmKeySize < 0)
        {
            throw Error.Common_PropertyMustBeNonNegative(nameof(configuration.EncryptionAlgorithmKeySize));
        }

        _logger.UsingManagedSymmetricAlgorithm(configuration.EncryptionAlgorithmType.FullName !);

        if (configuration.EncryptionAlgorithmType == typeof(Aes))
        {
            return(Aes.Create);
        }
        else
        {
            return(AlgorithmActivator.CreateFactory <SymmetricAlgorithm>(configuration.EncryptionAlgorithmType));
        }
    }
    private static ManagedAuthenticatedEncryptorConfiguration GetManagedAuthenticatedEncryptorConfiguration(RegistryKey key)
    {
        var options           = new ManagedAuthenticatedEncryptorConfiguration();
        var valueFromRegistry = key.GetValue(nameof(ManagedAuthenticatedEncryptorConfiguration.EncryptionAlgorithmType));

        if (valueFromRegistry != null)
        {
            options.EncryptionAlgorithmType = TypeExtensions.GetTypeWithTrimFriendlyErrorMessage(Convert.ToString(valueFromRegistry, CultureInfo.InvariantCulture) !);
        }

        valueFromRegistry = key.GetValue(nameof(ManagedAuthenticatedEncryptorConfiguration.EncryptionAlgorithmKeySize));
        if (valueFromRegistry != null)
        {
            options.EncryptionAlgorithmKeySize = Convert.ToInt32(valueFromRegistry, CultureInfo.InvariantCulture);
        }

        valueFromRegistry = key.GetValue(nameof(ManagedAuthenticatedEncryptorConfiguration.ValidationAlgorithmType));
        if (valueFromRegistry != null)
        {
            options.ValidationAlgorithmType = TypeExtensions.GetTypeWithTrimFriendlyErrorMessage(Convert.ToString(valueFromRegistry, CultureInfo.InvariantCulture) !);
        }

        return(options);
    }
Exemple #18
0
    public static IDataProtectionBuilder UseCustomCryptographicAlgorithms(this IDataProtectionBuilder builder, ManagedAuthenticatedEncryptorConfiguration configuration)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        if (configuration == null)
        {
            throw new ArgumentNullException(nameof(configuration));
        }

        return(UseCryptographicAlgorithmsCore(builder, configuration));
    }