Как создать экспортируемый ключ RSA с помощью RsaProtectedConfigurationProvider с методом ProtectSection в C# - PullRequest
2 голосов
/ 19 марта 2020

В следующем примере я защищаю раздел «DemoWinApp.Properties.Settings» файла «Sleutels.config».

    private static void toggleProtectionSleutelsConfig()
    {
        var fileMap = new ConfigurationFileMap(@"D:\Experimenten\ReadProtectedConfigFile\Sleutels.config");
        var configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
        var sectionGroup = configuration.GetSectionGroup("applicationSettings"); // This is the section group name, change to your needs
        var section = (ClientSettingsSection)sectionGroup.Sections.Get("DemoWinApp.Properties.Settings"); // This is the section name, change to your needs
        var setting = section.Settings.Get("SecretMessage"); // This is the setting name, change to your needs
        Console.WriteLine(setting.Value.ValueXml.InnerText);

        // Toggle beveiliging
        if (!section.SectionInformation.IsProtected)
        {
            //Protecting the specified section with the specified provider
            section.SectionInformation.ProtectSection("RSA");
        }
        else
        {
            section.SectionInformation.UnprotectSection();
        }
        section.SectionInformation.ForceSave = true;
        configuration.Save(ConfigurationSaveMode.Modified);


        Console.ReadKey();
    }

Содержимое файла «Sleutels.config»:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<configSections>
		<sectionGroup name="applicationSettings"

     type="System.Configuration.ApplicationSettingsGroup, &#xD;&#xA;                    System, Version=2.0.0.0, Culture=neutral, &#xD;&#xA;                    PublicKeyToken=b77a5c561934e089">
			<section name="DemoWinApp.Properties.Settings" type="System.Configuration.ClientSettingsSection, 
                      System, Version=2.0.0.0, Culture=neutral, 
                      PublicKeyToken=b77a5c561934e089" requirePermission="false" />
		</sectionGroup>
	</configSections>
	<applicationSettings>
		<DemoWinApp.Properties.Settings>
   <setting name="SecretMessage" serializeAs="String">
    <value>This is the secret message.</value>
   </setting>
  </DemoWinApp.Properties.Settings>
	</applicationSettings>
	<configProtectedData>
		<providers>
		<add name="RSA"
       type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=2.0.0.0,&#xD;&#xA;                    Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,&#xD;&#xA;                    processorArchitecture=MSIL"
       keyContainerName="RobinsKeys"
       useMachineContainer="true" />
		</providers>
	</configProtectedData>
</configuration>

После выполнения кода файл «Sleutels.config» зашифровывается и создается контейнер ключа RSA в C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys

Если я пытаюсь экспортировать контейнер ключа RSA с командной строкой:

c:\windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -pc "RobinsKeys" –exp

Затем я получаю сообщение об ошибке:

Exporting RSA Keys to file...
Key not valid for use in specified state.

Это означает, что контейнер ключа RSA не помечен как «экспортируемый». Если вы создадите контейнер ключей с помощью командной строки, то существует необязательный параметр «-exp», чтобы пометить ключ как экспортируемый.

Например: aspnet_regiis -p c "RobinsKeys" -exp

Доступна ли эта опция -exp при использовании метода section.SectionInformation.ProtectSection("RSA"); в коде или в качестве опции конфигурации в разделе поставщика RSA в файле конфигурации "Sleutels.config"?

Любая помощь приветствуется!

1 Ответ

1 голос
/ 23 марта 2020

Чтобы подвести итоги обсуждения, вам необходимо создать крипто-контейнер RSA программно , прежде чем вы сможете использовать его для хранения ключей RSA.

Причина в том, что RSAProtectedConfigurationProvider не имеет возможности сделать автоматически созданный контейнер ключей RSA экспортируемым.

Как вы уже писали в чате, этот обходной путь может быть достигнут следующий пример кода (я добавил вывод в консоль, напечатанные параметры RSA объяснены здесь ):

void Main()
{
   // Create the CspParameters object and set the key container
   // name used to store the RSA key pair.
   var cp = new System.Security.Cryptography.CspParameters();
   cp.Flags = System.Security.Cryptography.CspProviderFlags.UseMachineKeyStore;
   cp.KeyContainerName = "RobinsKeys";


   // Create a new instance of RSACryptoServiceProvider that accesses
   // the key container MyKeyContainerName.
   // If it is not already there, it will create a new exportable one, which is exportable.
   var myRSA = new System.Security.Cryptography.RSACryptoServiceProvider(cp);

   // print it on console
   Console.WriteLine($"=== Container: {cp.KeyContainerName} ===");
   Console.WriteLine(myRSA.ToXmlString(true).Replace("><", ">\n<")); 
}

, которые можно прочитать более подробно здесь . Приведенная ссылка также показывает, как

  • создать и сохранить пару ключей
  • получить ключ из контейнера
  • удалить ключ из контейнера

Может быть полезно получить список контейнеров, это обсуждается в отдельном вопросе .

Еще некоторую информацию о ключевых контейнерах вы можете найти в этом Статья Microsoft , также о доступных параметрах aspnet_regiis.

После создания контейнера RSA он может использоваться IIS. Важно понимать разницу между пользовательскими уровнями и контейнерами ключей машинного уровня, которые описаны в этой документации .


Пожалуйста, дайте мне знать, если чего-то не хватает в обсуждении, и я обновлю этот ответ.

...