Applies To.NET

Примечание. Изменено 22 июня 2023 г. для обновления решений и обходных решений

Примечание. Изменено 15 июня 2023 г. для обновления вариантов 4 и 5 

Фон

13 июня 2023 г. корпорация Майкрософт выпустила обновление для системы безопасности для платформа .NET Framework и .NET, которое влияет на импорт сертификатов X.509 средой выполнения. Эти изменения могут привести к тому, что импорт сертификата X.509 вызовет исключение CryptographicException в тех случаях, когда импорт был бы успешно выполнен до обновления.

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

Затронутого программного обеспечения

  • платформа .NET Framework 2.0

  • платформа .NET Framework 4.6.2, 4.7, 4.7.1, 4.7.2

  • платформа .NET Framework 4.8

  • платформа .NET Framework 4.8.1

  • .NET 6.0

  • .NET 7.0

Затронутые API

Описание изменения

До 13 июня 2023 г. изменение, когда платформа .NET Framework и .NET предоставляется двоичный BLOB-объект сертификата для импорта, платформа .NET Framework и .NET обычно делегируют проверку и импорт большого двоичного объекта в базовую ОС. Например, в Windows платформа .NET Framework и .NET обычно используют API PFXImportCertStore для проверки и импорта.

По состоянию на 13 июня 2023 г. изменение, когда платформа .NET Framework и .NET предоставляется двоичный blob-объект сертификата для импорта, платформа .NET Framework и .NET в некоторых случаях будут выполнять дополнительную проверку, прежде чем передать большой двоичный объект в базовую ОС. Эта дополнительная проверка выполняет ряд эвристических проверок, чтобы определить, будет ли входящий сертификат злонамеренно исчерпать ресурсы при импорте. Так как это дополнительная проверка, которая обычно выполняется базовой ОС, она может блокировать blob-объекты сертификата, которые успешно импортировались до изменения 13 июня 2023 г.

Известные регрессии

  1. Если сертификат X.509 экспортирован в виде большого двоичного объекта PFX с редко высоким числом итерации паролей, импорт этого сертификата может завершиться ошибкой. Большинство средств экспорта сертификатов используют количество итераций в диапазоне от 2000 до 10 000. После применения обновления для системы безопасности произойдет сбой импорта сертификатов, содержащих число итераций, превышающее 600 000.

  2. Если сертификат X.509 был экспортирован с использованием пароля null [например, черезX509Certificate.Export(X509ContentType.Pfx, (string)null)или без пароляX509Certificate.Export(X509ContentType.Pfx)], этот сертификат теперь может не выполнить импорт.  

    Примечание: Указанная выше регрессия устранена в обновлении от 22 июня 2023 г., описанном в статье KB5028608.

  3. Если сертификат X.509 был экспортирован в виде большого двоичного объекта PFX с помощью возможности Windows для защиты закрытого ключа в идентификатор безопасности, этот сертификат может не импортироваться. Это повлияет на большие двоичные объекты PFX, созданные следующим образом:

    • С помощью мастера экспорта сертификатов Windows и указания в мастере, что закрытый ключ должен быть защищен для пользователя домена; Или

    • С помощью командлета Export-PfxCertificate PowerShell, где предоставляется явный аргумент -ProtectTo ; Или

    • Через служебную программу certutil , где указан явный аргумент -protectto ; Или

    • Через API PFXExportCertStoreEx, где предоставляется флаг PKCS12_PROTECT_TO_DOMAIN_SIDS.

Обходные решения & решения

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

Вариант 1 (предпочтительный) — установка обновленного исправления

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

Применимость. Этот параметр применяется ко всем версиям платформа .NET Framework и .NET.

Эта проблема устранена в обновлении от 22 июня 2023 г., описанном в обновлении KB5028608.

Корпорация Майкрософт рекомендует клиентам, у которых возникла регрессия, появившаяся в выпуске от 13 июня 2023 г., попробовать установить это обновленное исправление, прежде чем пытаться воспользоваться обходными решениями, перечисленными далее в этом документе.

Вариант 2. Изменение сайта звонков

Применимость. Этот параметр применяется ко всем версиям платформа .NET Framework и .NET.

Подумайте, является ли импортируемый BLOB-объект надежным. Например, был ли большой двоичный объект получен из надежного расположения, например из базы данных или файла конфигурации под вашим управлением, или он был предоставлен с помощью сетевого запроса, сделанного клиентом без проверки подлинности или непривилегированным клиентом?

Корпорация Майкрософт настоятельно рекомендует не импортировать большие двоичные объекты PFX, предоставленные клиентами без проверки подлинности или непривилегированными клиентами, так как эти blob-объекты могут содержать вредоносные реакции на исчерпание ресурсов.

Если вам нужно импортировать большой двоичный объект сертификата открытого ключа, предоставленный ненадежной стороной, можно использовать следующий код для безопасного импорта такого BLOB-объекта. В этом примере кода используется метод GetCertContentType для определения базового типа большого двоичного объекта сертификата и он отклоняет большие двоичные объекты PFX в тех случаях, когда требуется импортировать только большой двоичный объект сертификата с открытым ключом. КонструкторX509Certificate2(byte[]) безопасен для использования при получении ненадежных больших двоичных объектов, не относящихся к PFX.

using System.Security.Cryptography.X509Certificates;
public static X509Certificate2 ImportPublicCertificateBlob(byte[] blob)
{
     if (X509Certificate2.GetCertContentType(blob) == X509ContentType.Pfx)
    {
          throw new Exception("PFX blobs are disallowed.");
    }
   else
   {
         // Import only after we have confirmed it's not a PFX.
        return new X509Certificate2(blob);
    }
} 

Если вам нужно импортировать большой двоичный объект сертификата закрытого ключа без пароля и вы определили, что большой двоичный объект является надежным, можно отключить дополнительные проверки, выполненные 13 июня 2023 г., путем вызова другой перегрузки конструктора. Например, можно вызвать перегрузку конструктора, которая принимает строковый аргумент пароля и передает значение NULL для значения аргумента. 

byte[] blobToImport = GetBlobToImport(); // fetch this from a database, config, etc. 

// REGRESSION - byte[] ctor performs additional security checks X509Certificate2 certA = new X509Certificate2(blobToImport);

// RECOMMENDED WORKAROUND - different ctor overload suppresses additional security checks X509Certificate2 certB = new X509Certificate2(blobToImport, (string)null);

Вариант 3. Изменение или подавление дополнительной проверки с помощью переменной среды

Применимость. Этот параметр применяется только ко всем версиям платформа .NET Framework.  Он не применяется к .NET 6.0 и более поздних версий.

Хотя платформа .NET Framework по умолчанию ограничить операции импорта не более 600 000 итераций пароля, это ограничение можно настроить на уровне приложения или компьютера с помощью переменной среды. Это новое ограничение будет применяться ко всем вызовам затронутых API, перечисленных выше.

Чтобы изменить ограничение, задайте для переменной средыCOMPlus_Pkcs12UnspecifiedPasswordIterationLimitзначение нового ограничения. Например, чтобы задать ограничение в 1 000 000 (один миллион) итераций, задайте переменную среды, как показано ниже.

  • Это число управляет общим ограничением итерации, которое представляет собой сумму количества итерации MAC, зашифрованное безопасное содержимое и количество итерации окутанной сумки. Если вы вручную экспортировали PFX с помощью явного числа итерации <iter_count> (например, через openssl pkcs12 -export -iter <iter_count>) и хотите импортировать этот большой двоичный объект PFX, задайте для этой переменной среды значение, по крайней мере равное сумме всех ожидаемых итераций. На практике платформа .NET Framework и .NET может позволить общему количеству итераций немного превысить любое явно настроенное ограничение.

COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=1000000

Чтобы полностью отключить дополнительные проверки, задайте для переменной среды специальное значение sentinel -1, как показано ниже.

  • ⚠️ Предупреждение. Задайте для переменной среды значение -1 только в том случае, если вы уверены, что целевое приложение не обрабатывает ненадежные входные данные сертификата.

COMPlus_Pkcs12UnspecifiedPasswordIterationLimit=-1

Вариант 4. Изменение или подавление дополнительной проверки с помощью AppContext

Применимость. Этот параметр применяется только к .NET 6.0+.  Это не относится к платформа .NET Framework

Хотя .NET по умолчанию ограничивает операции импорта не более 600 000 итераций пароля, это ограничение можно настроить для всего приложения с помощью параметра AppContext. Это новое ограничение будет применяться ко всем вызовам затронутых API, перечисленных выше.

Чтобы изменить ограничение, задайте параметру AppContext System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit значение нового ограничения. Например, чтобы задать ограничение в 1 000 000 (один миллион) итераций, установите переключатель, как показано ниже.

  • Это число управляет общим ограничением итерации, которое представляет собой сумму количества итерации MAC, зашифрованное безопасное содержимое и количество итерации окутанной сумки. Если вы вручную экспортировали PFX с помощью явного числа итерации <iter_count> (например, через openssl pkcs12 -export -iter <iter_count>) и хотите импортировать этот большой двоичный объект PFX, задайте для этой переменной среды значение, по крайней мере равное сумме всех ожидаемых итераций. На практике .NET может позволить общему количеству итераций немного превысить любое явное ограничение, заданное здесь.

Чтобы задать параметр в файле проекта приложения (CSPROJ или VBPROJ), выполните следующие действия:

<!--

  • This switch only works if the current project file represents an application. It has no effect if the current project file represents a shared library.

-->

<ItemGroup>

  • <RuntimeHostConfigurationOption Include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" Value="1000000" />

</ItemGroup>

Кроме того, можно поместить файл с именем runtimeconfig.template.json со следующим содержимым в том же каталоге, который содержит файл проекта приложения:

{

     "configProperties": {

  • "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": 1000000

      }

}

Дополнительные сведения об изменении параметров конфигурации среды выполнения .NET см. на странице документации параметры конфигурации среды выполнения .NET.

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

⚠️ Предупреждение. Задайте для параметра AppContext значение -1 только в том случае, если вы уверены, что целевое приложение не обрабатывает ненадежные входные данные сертификата.

В файле проекта приложения (CSPROJ или VBPROJ):

<!--

  • This switch only works if the current project file represents an application. It has no effect if the current project file represents a shared library.

-->

<ItemGroup>

  • <RuntimeHostConfigurationOption Include="System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit" Value="-1" />

</ItemGroup>

Или в файле runtimeconfig.template.json:

{

  • "configProperties": { 
  •     "System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit": -1

     }

}

Вариант 5. Изменение или подавление дополнительной проверки на уровне компьютера через реестр (только для Windows для платформа .NET Framework)

Применимость. Этот параметр применяется только ко всем версиям платформа .NET Framework.  Он не применяется к .NET 6.0 и более поздних версий.

Хотя платформа .NET Framework по умолчанию ограничение операций импорта не более 600 000 итераций пароля, это ограничение можно настроить на уровне компьютера с помощью реестра HKLM. Это новое ограничение будет применяться ко всем вызовам затронутых API, перечисленных выше.

Чтобы изменить ограничение, в разделе реестраHKLM\Software\Microsoft\.NETFrameworkзадайте дляPkcs12UnspecifiedPasswordIterationLimitзначение нового ограничения. Например, чтобы установить ограничение в 1 000 000 (один миллион) итераций, выполните команды, как показано ниже, из командной строки с повышенными привилегиями.

  • Это число управляет общим ограничением итерации, которое представляет собой сумму количества итерации MAC, зашифрованное безопасное содержимое и количество итерации окутанной сумки. Если вы вручную экспортировали PFX с помощью явного числа итерации <iter_count> (например, с помощью openssl pkcs12 -export -iter <iter_count>) и хотите импортировать этот большой двоичный объект PFX, задайте для этого значения реестра значение, по крайней мере равное сумме всех ожидаемых итераций. На практике платформа .NET Framework может позволить общему количеству итераций немного превысить любое явное ограничение, заданное здесь.

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

reg add "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /t REG_DWORD /d 1000000 /reg:32 reg add "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /t REG_DWORD /d 1000000 /reg:64

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

  • ⚠️ Предупреждение. Задайте для реестра значение -1 только в том случае, если вы уверены, что службы, работающие на целевом компьютере, не обрабатывают ненадежные входные данные сертификата.

  • Чтобы задать -1 sentinel, используйте тип REG_SZ вместо типа REG_DWORD. Параметр реестра зависит от архитектуры. Чтобы приложения соблюдали настроенное значение независимо от целевой архитектуры, не забудьте изменить как 32-разрядные, так и 64-разрядные реестры, как показано ниже.

reg add "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /t REG_SZ /d -1 /reg:32 reg add "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /t REG_SZ /d -1 /reg:64

Чтобы отменить изменения изменения реестра, удалите значение reg Pkcs12UnspecifiedPasswordIterationLimit из командной строки с повышенными привилегиями.

reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:32 reg delete "HKLM\Software\Microsoft\.NETFramework" /v Pkcs12UnspecifiedPasswordIterationLimit /reg:64

Заметки для Windows

В Windows платформа .NET Framework импортировать сертификаты с помощью функции PFXImportCertStore. Эта функция выполняет собственную проверку, в том числе устанавливает собственные ограничения на максимально допустимое число итераций большого двоичного объекта PFX. Эти проверки по-прежнему будут выполняться при импорте PFX. Teh. Описанные выше переменные среды и разделы реестра, относящиеся к NET, не влияют на то, как PFXImportCertStore выполняет эти проверки.

Нужна дополнительная помощь?

Нужны дополнительные параметры?

Изучите преимущества подписки, просмотрите учебные курсы, узнайте, как защитить свое устройство и т. д.

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