Хранилище сертификатов Windows на практике — пользователь или компьютер

· Обновлено: · · Сертификаты, Windows, Безопасность, PKI, TLS, PowerShell, Бизнес-приложения, Информационные системы

История изменений (1 обновлений, последнее 31 Aug 2026)

Журнал изменений этой статьи. Там, где версия до правки была заархивирована, она остаётся доступной для чтения по постоянной ссылке с DOI.

Русский текст переписан по текущему навыку технического перевода как полный перевод японского оригинала.
Первая публикация
Цитирование статьи(DOI (зарегистрированный архив): 10.5281/zenodo.22175582)

Приведённые ниже DOI относятся к ранее зарегистрированным архивным версиям, которые могут отличаться от текущего текста. Для ссылки на текущий текст используйте URL этой страницы.

Го Комура (2026). Хранилище сертификатов Windows на практике — пользователь или компьютер. KomuraSoft LLC. https://comcomponent.com/ru/blog/windows-certificate-store-guide/

DOI (зарегистрированный архив)
10.5281/zenodo.22175582
DOI (последняя зарегистрированная версия)
10.5281/zenodo.22175583

«После обновления терминала онлайн-проверки страхового статуса клиентский сертификат перенесли на новый ПК — и соединение пропало.» «На машине разработки банковский API открывается, а когда оформили службу Windows, пишет „сертификат не найден“.» «Вообще непонятно, какой сертификат настоящий — тот, что видно в certmgr.msc, или тот, что в certlm.msc.» — когда по заказной разработке делают интеграцию Web API с клиентским сертификатом, такие обращения приходят регулярно.

Онлайн-проверка страхового статуса в медучреждениях, электронная подача документов, банковские API, EDI с контрагентами. Клиентскими сертификатами, которыми когда-то занимались только инфраструктурщики крупных компаний, теперь пользуются ИТ малого и среднего бизнеса и разработчики бизнес-приложений. А сбои вокруг сертификатов на деле сводятся к горстке шаблонов. Помещают не туда, забывают права на закрытый ключ, забывают срок — эти три.

Статья рассчитана на разработчиков бизнес-приложений, которые используют клиентские сертификаты, и на ИТ-сотрудников, которым поручают замену сертификатов. Вокруг решения, куда помещать сертификат — в хранилище пользователя или компьютера, — за один проход разбираем структуру хранилища сертификатов Windows, назначение прав на закрытый ключ, инвентаризацию сроков через PowerShell и код использования из .NET. Содержание опирается на первоисточники Microsoft Learn по состоянию на август 2026.

1. Сначала выводы

  • Хранилище сертификатов Windows бывает двух типов: «пользователь» (CurrentUser) и «компьютер» (LocalMachine). Хранилище пользователя у каждой учётной записи своё (в реестре под HKEY_CURRENT_USER), хранилище компьютера общее на весь ПК (под HKEY_LOCAL_MACHINE).12
  • Средств управления тоже два. certmgr.msc открывает хранилище текущего пользователя, certlm.msc — локального компьютера. Из PowerShell это Cert:\CurrentUser и Cert:\LocalMachine.34
  • Куда помещать, решает учётная запись, от имени которой работает программа. Как правило, приложение интерактивного пользователя — хранилище пользователя; запуск без интерактивного пользователя — служба Windows, IIS, Планировщик заданий — хранилище компьютера (таблица решений главы 3).
  • Причина «на разработке работало, а после оформления службой сертификат не находится» почти всегда одна. Сертификат, который разработчик импортировал в своё хранилище пользователя, из CurrentUser службы под другой учётной записью невидим (глава 3).
  • Сертификат и закрытый ключ — разные вещи. Одного размещения сертификата в хранилище компьютера недостаточно, чтобы учётная запись службы читала закрытый ключ — это обычная ситуация. Выдайте учётной записи выполнения право на чтение через «Управление закрытыми ключами» в certlm.msc.5
  • При импорте pfx закрытый ключ по умолчанию нельзя экспортировать. Import-PfxCertificate принимает закрытый ключ в форме, из которой его нельзя экспортировать снова, пока не указан -Exportable. Это не сбой, а желаемое значение по умолчанию.6
  • Истечение срока предотвращают автоматизацией инвентаризации. Get-ChildItem Cert:\LocalMachine\My -ExpiringInDays 60 механически отбирает сертификаты, которые истекают в пределах заданного числа дней.4
  • Отпечаток (thumbprint), жёстко заданный в коде или конфигурации, ломает работу при каждом обновлении сертификата, потому что у нового сертификата отпечаток всегда другой. Вынести в конфигурацию плюс период параллельной работы старого и нового — базовая конструкция (главы 5 и 7).

На схеме сплошная линия обозначает отношение, которое выполняется всегда, а пунктирная — условное отношение (условия указаны в пояснении к каждому отношению на странице сведений). Полный список отношений (всего 41, с доказательствами и степенью уверенности) и определения основных понятий собраны на странице сведений карты знаний (на японском). Данные: JSON-LD / Turtle

2. Общая картина хранилища сертификатов — два расположения и логические хранилища

2.1. Два типа: пользователь и компьютер

Хранилище сертификатов Windows в целом делится на два «расположения».1

  • Хранилище сертификатов компьютера (локальный компьютер, LocalMachine): одно на ПК, общее для всех пользователей и служб на этом ПК. Физически живёт под ключом реестра HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates.2
  • Хранилище сертификатов пользователя (текущий пользователь, CurrentUser): у каждой учётной записи своё. Физически живёт под HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates, то есть как часть профиля пользователя.2

Есть ещё хранилище на учётную запись службы,3 физически — ключ реестра на имя службы.2 Для практики сначала нужно освоить первые два.

Есть одна важная особенность. Каждое логическое хранилище хранилища пользователя, кроме «Личные», наследует и показывает содержимое одноимённого хранилища компьютера.1 Например, если поместить сертификат корпоративного CA в «Доверенные корневые центры сертификации» хранилища компьютера, он появится и в «Доверенных корневых центрах сертификации» каждого пользователя. Наоборот, наследуется всё, кроме хранилища «Личные», поэтому для клиентского сертификата (того, что помещают в «Личные») вы сами решаете, «кому нужно его видеть». На этой асимметрии строится вся статья.

Хранилище компьютера и хранилище пользователяХранилище компьютера одно на ПК и общее для всех пользователей и служб; хранилище пользователя своё у каждой учётной записи, и кроме «Личные» наследует содержимое хранилища компьютераПользователь (CurrentUser)У каждой учётной записи своёКомпьютер (LocalMachine)Одно на ПК, общее для всех пользователей и службсодержимое видно через наследованиенаследованиенаследованиеЛичные (My)не наследуется = место выбираете самиДоверенные корневые центры сертификации (Root)Промежуточные центры сертификации (CA)Доверенные издатели (TrustedPublisher)Личные (My)Доверенные корневые центры сертификации (Root)Промежуточные центры сертификации (CA)Доверенные издатели (TrustedPublisher)

Рис. 1: Хранилище пользователя, кроме «Личные», наследует содержимое хранилища компьютера; куда помещать клиентский сертификат, решаете сами.

2.2. Основные логические хранилища

Внутри каждого расположения содержимое разделено на логические хранилища по роли. Это папки, которые видно в certmgr.msc / certlm.msc; из PowerShell и командной строки используют английские внутренние имена.24

Отображаемое имя Внутреннее имя Что сюда помещают
Личные My Сертификаты, которыми пользуется этот ПК / этот пользователь. Сюда — клиентские и серверные. Сюда же привязывается закрытый ключ
Доверенные корневые центры сертификации Root Сертификаты корневого CA — якорь доверия. Всё под CA, помещённым сюда, «доверяется»
Промежуточные центры сертификации CA Сертификаты промежуточного CA между корнем и оконечным. Материал построения цепочки
Доверенные издатели TrustedPublisher Сертификаты, которым доверяют как издателю подписанного ПО (глава 8)

2.3. Три способа просмотра — certmgr.msc / certlm.msc / диск Cert:

Одно и то же хранилище смотрят тремя средствами.34

  • certmgr.msc: консоль управления, открывающая хранилище текущего пользователя.
  • certlm.msc: консоль управления, открывающая хранилище локального компьютера.
  • Диск PowerShell Cert:: иерархия Cert:\CurrentUser\... и Cert:\LocalMachine\... позволяет обращаться с хранилищем как с файловой системой. Сертификаты идентифицируются отпечатком.

Если оснастку сертификатов добавляют в mmc.exe вручную, цель выбирают из трёх видов: «учётная запись пользователя», «учётная запись компьютера», «учётная запись службы». Пользователь без прав администратора может управлять только хранилищем своей учётной записи пользователя.3

Первый шаг при разборе сбоя — совместить «какое хранилище смотрит приложение» и «какое хранилище смотрите вы». Пока вы смотрите certmgr.msc и разбираете сбой службы, расположения разные, и ответа не будет никогда.

3. Куда помещать — таблица решений по форме выполнения программы

Критерий один. Под чьей учётной записью работает программа, которая этот сертификат использует.

Форма выполнения Учётная запись выполнения Куда помещать Примечание
Настольное приложение, которое запускает интерактивный пользователь Сам вошедший в систему пользователь Пользователь (Cert:\CurrentUser\My) Нужно внедрять на каждую учётную запись пользователя. Если общим ПК пользуются несколько человек, рассмотрите и хранилище компьютера
Служба Windows LocalSystem / NETWORK SERVICE / выделенная учётная запись службы Компьютер (Cert:\LocalMachine\My) Всем, кроме LocalSystem (NETWORK SERVICE, выделенная учётная запись и т. п.), обязательно выдать право читать закрытый ключ (глава 4). LocalSystem читает правом SYSTEM по умолчанию
Веб-приложение на IIS Удостоверение пула приложений Компьютер То же
Запуск Планировщика заданий без интерактивного пользователя (выполнять независимо от регистрации пользователя) Учётная запись, указанная заданию Рекомендуется компьютер Можно и хранилище пользователя учётной записи выполнения, но растёт только проверка профиля и видимости хранилища, выгоды мало
Электронная подача документов и веб-аутентификация в браузере Сам вошедший в систему пользователь Пользователь Естественно и в смысле «не давать пользоваться никому, кроме того, кому раздали»

Если сомневаетесь: то, что работает без интерактивного пользователя, — хранилище компьютера; то, чем управляет человек, — хранилище пользователя.

3.1. Разбор типичного сбоя — «на разработке работало, а после оформления службой сертификат не находится»

Этот сбой точно воспроизводят следующим порядком.

  1. Разработчик на своём ПК дважды щёлкает pfx и импортирует. Значение мастера по умолчанию — «текущий пользователь», поэтому сертификат попадает в хранилище пользователя учётной записи разработчика.
  2. Приложение в разработке запускается из Visual Studio, то есть под учётной записью разработчика, открывает StoreLocation.CurrentUser — сертификат находится. Работает.
  3. На рабочем сервере регистрируют как службу Windows. Служба работает под NETWORK SERVICE или выделенной учётной записью.
  4. CurrentUser, который открывает код службы, — хранилище пользователя учётной записи службы. Оно пусто. «Сертификат не найден».
На разработке работало, как служба — не находитсяСертификат, помещённый в хранилище пользователя разработчика, не виден из CurrentUser службы, которая работает под другой учётной записьюРабочий серверМашина разработкиразмещают ту же программуCurrentUser, который открывает код,— хранилище пользователя учётной записи службыРегистрация как службы Windowsучётная запись выполнения — NETWORK SERVICE и т. п.Оно пусто→ «сертификат не найден»Попадает в хранилище пользователяучётной записи разработчикаИмпорт двойным щелчком pfxзначение мастера по умолчанию — «текущий пользователь»Запуск из Visual Studio= работает под учётной записью разработчикаОткрыть CurrentUser — находится→ работает

Рис. 2: Хранилище пользователя разработчика и хранилище пользователя учётной записи службы — разные; работа на разработке не гарантирует, что сертификат найдётся в production.

Суть в том, что хранилищ пользователя «столько, сколько учётных записей». Даже если администратор откроет certmgr.msc и скажет «да вот же лежит», это хранилище самого администратора, а не хранилище учётной записи службы. Мера — не копировать по случаю, а поместить заново в хранилище компьютера и привести код к StoreLocation.LocalMachine. И в комплект входит назначение прав следующей главы.

4. Закрытый ключ и права доступа — второй типичный сбой

4.1. Сертификат и закрытый ключ — разные вещи

В списке хранилища сертификатов виден сертификат (открытые сведения), а не сам закрытый ключ. Для клиентской аутентификации на деле нужна подпись закрытым ключом, поэтому «видно в списке» и «можно пользоваться» — разные проблемы. Если их смешать, получаются плохо читаемые снаружи сбои: «сертификат есть, но TLS-рукопожатие падает», «внутренние ошибки вроде Access Denied».

4.2. Практика импорта pfx — возможность экспорта есть отдельное решение

Пару сертификат + закрытый ключ передают файлом pfx (PKCS #12) и принимают в хранилище Import-PfxCertificate.6

$pwd = Get-Credential -UserName '(пароль введите ниже)' -Message 'Пароль PFX'
Import-PfxCertificate -FilePath C:\certs\client.pfx `
    -CertStoreLocation Cert:\LocalMachine\My -Password $pwd.Password

Важно: пока не указан -Exportable, принятый закрытый ключ нельзя экспортировать снова — поведение по умолчанию.6 Импортировать всё как экспортируемое «чтобы потом можно было перенести» — добавить ещё один путь утечки закрытого ключа. Оригинал pfx хранят безопасно, а закрытый ключ в хранилище по умолчанию неэкспортируемый — так рекомендуем мы. Оригинал pfx и его пароль как раз часто оставляют открытым текстом. Подход разобран в «Хранение секретов в Windows-приложениях — как не оставлять настройки открытым текстом, DPAPI» и «Безопасная работа с учётными данными в PowerShell».

4.3. Назначение прав на закрытый ключ учётной записи службы

Закрытый ключ сертификата, помещённого в хранилище компьютера, по умолчанию обычно не читают ниоткуда, кроме администраторов и SYSTEM. Поэтому служба под LocalSystem читает закрытый ключ как есть, а если работает под NETWORK SERVICE, выделенной учётной записью службы, удостоверением пула приложений IIS и т. п. — всем, кроме этого, явно выдайте учётной записи выполнения право на чтение. Шаги — из UI оснастки сертификатов.5

  1. Открыть certlm.msc (или оснастку сертификатов с целью «учётная запись компьютера»).
  2. «Личные» → «Сертификаты», правый щелчок по нужному сертификату, «Все задачи» → «Управление закрытыми ключами».
  3. На вкладке «Безопасность» добавить учётную запись выполнения (NETWORK SERVICE, выделенная учётная запись службы, удостоверение пула приложений IIS и т. п.) и разрешить «Чтение».5

Полный доступ не нужен. Для подписи достаточно чтения. Наоборот, выдать Everyone полный доступ «потому что не работает» — обращаться с закрытым ключом как с паролем в открытом виде; этого нельзя допускать ни в коем случае. Размещение в хранилище компьютера и назначение прав на закрытый ключ всегда идут вместе — одной этой фразой в инструкции этот класс сбоев исчезает.

5. Как не допустить сбой из-за истечения срока — инвентаризация, замена, таблица учёта

5.1. Инвентаризация через PowerShell

Срок действия сертификата лежит в свойстве NotAfter. Инвентаризировать механически можно Get-ChildItem по диску Cert:.4

# Хранилище «Личные» компьютера списком по сроку действия
Get-ChildItem Cert:\LocalMachine\My |
    Sort-Object NotAfter |
    Format-Table Thumbprint, Subject, NotAfter

# Только те, что истекают в пределах 60 дней (0 — уже истёкшие)
Get-ChildItem -Path Cert:\LocalMachine\My -ExpiringInDays 60

-ExpiringInDays возвращает «сертификаты, которые истекают в пределах заданного числа дней»; 0 даёт уже истёкшие.4 Сделайте это ежемесячным заданием Планировщика по всем серверам и сводите результат в почту или таблицу учёта — и сбои вида «истёк срок, с утра понедельника проверка страхового статуса не проходит» почти исчезают.

5.2. Порядок замены — период параллельной работы и ловушка отпечатка

Обновление сертификата — не «удалить и поместить», а «добавить, затем переключить, проверить, затем удалить».

  1. Импортировать новый сертификат (pfx) в то же хранилище. Отпечатки разные, поэтому старый и новый могут сосуществовать в одном хранилище.
  2. Выдать права на закрытый ключ нового сертификата (глава 4). При обновлении об этом забывают чаще всего. Права висят на закрытом ключе каждого сертификата, поэтому после замены сертификата назначение делают заново.
  3. Уведомление контрагента (API, где сертификат нужно регистрировать заранее) сначала, продолжая работать на старом сертификате, и обеспечить период, когда принимают и старый, и новый. Если переключить раньше, контрагент отвергнет новый сертификат, и обмен в production встанет.
  4. Переключить конфигурацию приложения на новый сертификат и проверить работу.
  5. После достаточного периода удалить старый сертификат.
Обновление сертификата — сначала добавить, затем переключитьНовый pfx помещают в то же хранилище, выдают права, заранее регистрируют у контрагента, затем переключают отпечаток и после периода параллельной работы удаляют старый сертификат1. Импорт нового pfx в то же хранилище(старый и новый сосуществуют)2. Выдать права на закрытый ключнового сертификата3. Заранее зарегистрировать у контрагента(продолжать работу на старом)4. Переписать отпечаток в конфигурации,переключить, проверить работу5. После периода параллельной работыудалить старый сертификат

Рис. 3: Порядок замены сертификата — добавить → выдать права → заранее зарегистрировать → сменить конфигурацию → удалить старый; не забудьте обновить отпечаток.

Главная ловушка здесь — отпечаток, записанный в файл конфигурации или в код. Отпечаток уникален на сертификат, при обновлении он обязательно меняется. Если хоть в одном месте остаётся ссылка на старый отпечаток, получается «сертификат обновили, а соединиться нельзя». Надёжно вести в таблице учёта, где отпечаток записан (конфигурация приложения, привязка IIS, скрипты, уведомление контрагента).

5.3. Зачем нужна таблица учёта сертификатов

Таблица учёта — для начала хватит одного листа Excel. Минимум колонок: назначение / издатель / субъект / отпечаток / место (имя сервера + хранилище) / учётные записи с правом на закрытый ключ / срок действия / ссылка на процедуру обновления / ответственный — и сверять с результатом инвентаризации 5.1. Суть сбоев с сертификатами — не техника, а «ни у кого нет списка», поэтому таблица учёта действует сильнее всего.

6. Проверка и разбор сбоя — цепочка и распространение корневого сертификата

6.1. База проверки цепочки и certutil

Ошибки вида «этому сертификату не доверяют» — состояние, в котором цепочка (путь сертификации) от оконечного сертификата до корневого CA где-то разорвана. Для локализации удобен certutil.7

Три типичные причины разрыва проверки цепочкиОшибка доверия возникает, когда промежуточный CA получить нельзя, корень не распространён или оконечный сертификат истёкполучить нельзя(ни предъявление, ни AIA, ни хранилище)не распространёнистёкОконечный сертификат(клиентский, серверный)Сертификат промежуточного CAместо: хранилище промежуточных CA (CA)Сертификат корневого CAместо: доверенные корневые CA (Root)Цепочку построить нельзя(типичная причина 1)Ошибка «не доверяют»(типичная причина 2)Ошибка срока действия(типичная причина 3)

Рис. 4: Цепочка рвётся, если нет промежуточного CA или корня, либо из-за срока действия; слой определяют через certutil.

:: Построить и проверить цепочку файла сертификата (с получением URL отзыва)
certutil -urlfetch -verify client.cer

:: Если целевое приложение использует хранилище пользователя — тот же контекст с -user
certutil -user -urlfetch -verify client.cer

:: Дамп содержимого хранилища (-user — хранилище пользователя)
certutil -store My
certutil -user -store My

certutil -verify проверяет сертификат, CRL и цепочку и, если CACertFile не задан, строит полную цепочку и проверяет её.7 Вывод длинный, но из него читается, на каком уровне оборвалось доверие и получены ли сведения об отзыве. Типичные причины: (1) сертификат промежуточного CA получить нельзя (собеседник TLS его не прислал, из сведений AIA сертификата тоже не взять, в хранилище «Промежуточные центры сертификации» его нет); (2) корень корпоративного CA не распространён в «Доверенные корневые центры сертификации»; (3) истёк сам сертификат. Промежуточный CA решается и предъявлением собеседника, и автоматическим получением через AIA, поэтому размещение в хранилище — «один из способов сделать надёжно».

6.2. Распространение корня корпоративного CA и самоподписанного — через GPO/Intune

Если используете корпоративный CA или самоподписанный сертификат для проверки, его корневой сертификат нужно распространить на каждый ПК. Не помещать вручную по одной машине, а разворачивать через механизм распространения.

  • Среда Active Directory (GPO): импорт сертификата в «Доверенные корневые центры сертификации» в Конфигурация компьютера\Политики\Конфигурация Windows\Параметры безопасности\Политики открытого ключа распространяет его на целевые ПК.8
  • Среда управления Intune: профилем «Доверенный сертификат» распространяют корневой / промежуточный сертификат CA. В Windows можно выбрать целевое хранилище (корень / промежуточный компьютера, промежуточный пользователя).9

Как сказано в 2.1, поместив в корень хранилища компьютера, доверяют все пользователи.1 Поэтому смотрите и на обратный риск. Поместить самоподписанный сертификат в «Доверенные корневые центры сертификации» — добавить на этот ПК новый якорь доверия. Если его закрытый ключ утечёт, появляется возможность выпускать сертификаты, выдающие себя за любой сайт или ПО. Для постоянной эксплуатации — либо корпоративный CA с надлежащей защитой закрытого ключа, либо сертификаты публичного CA; самоподписанный корень — принцип «только среда проверки, со сроком».

7. Взгляд разработчика — правильно пользоваться хранилищем из .NET

7.1. Поиск по отпечатку через X509Store

Из .NET хранилище открывают X509Store и получают сертификат через Find.1011

using System.Security.Cryptography.X509Certificates;

static X509Certificate2 GetClientCertificate(string thumbprint)
{
    using var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

    var found = store.Certificates.Find(
        X509FindType.FindByThumbprint, thumbprint, validOnly: true);

    if (found.Count == 0)
        throw new InvalidOperationException(
            $"Сертификат не найден: отпечаток={thumbprint}, " +
            $"место={store.Location}\\{store.Name}");

    var cert = found[0];
    if (!cert.HasPrivateKey)
        throw new InvalidOperationException(
            $"Сертификат есть, но закрытый ключ не связан (импорт " +
            $"из .cer и т. п.): отпечаток={thumbprint}, место={store.Location}\\{store.Name}");

    return cert;
}

Решение главы 3 сюда стыкуется напрямую. Код, работающий как служба, — StoreLocation.LocalMachine; интерактивное приложение — StoreLocation.CurrentUser. Ещё одно: третий аргумент Find, validOnly. true возвращает только действительные сертификаты, прошедшие проверку.11 Это страховка не схватить истёкший, но тестовый самоподписанный, которому цепочка не доверяет, тоже падает в «не найден» — когда «лежит, а не находится», подозревайте и это. И в сообщение об ошибке, когда не найден, как в примере выше, обязательно включайте, какое хранилище искали. Время разбора сбоя главы 3 меняется на порядки.

7.2. Положить клиентский сертификат в HttpClient

Полученный сертификат добавляют в HttpClientHandler.ClientCertificates и предъявляют серверу. Эта коллекция — множество сертификатов, предъявляемых серверу при аутентификации клиента по сертификату.12

var handler = new HttpClientHandler();
handler.ClientCertificates.Add(GetClientCertificate(thumbprint));

var client = new HttpClient(handler);
// дальше — обычный HttpClient

В семействе .NET Core в документации прямо сказано: если у сертификата есть атрибут Key Usage, без «Digital Signature» он не используется при отправке запроса.12 Когда заказываете выпуск клиентского сертификата, правильно передавайте назначение (аутентификация клиента). Кроме того, HttpClient при неверном шаблоне создания даёт исчерпание сокетов и проблемы следования за DNS. Конструкцию с долгоживущим обработчиком разбирали в «Не оборачивайте HttpClient в using».

7.3. Проблема отпечатка в коде: при замене он ломает работу

Поиск по отпечатку надёжен, но если отпечаток вшить в код, при каждом обновлении сертификата нужны сборка и выпуск. Мера в проекте — три ступени.

  • Минимум: вынести отпечаток в файл конфигурации (appsettings и т. п.), чтобы менять без выпуска. Место конфигурации занести в таблицу учёта 5.3.
  • Шаг дальше: искать по имени субъекта или издателю и в сочетании с validOnly: true выбирать «из сейчас действительных с этим именем тот, у кого NotAfter дальше всех». В период параллельной работы старого и нового автоматически переключится на новый сертификат. Но есть риск схватить одноимённый непреднамеренный сертификат, поэтому в комплект — проверка издателя и вывод в журнал. И это автоматическое переключение работает только если контрагенту не нужна предварительная регистрация сертификата. В API, где регистрация нужна (5.2), самовольное переключение на только что импортированный незарегистрированный сертификат может остановить обмен — оставайтесь на вынесении в конфигурацию с переключением после подтверждения регистрации.
  • Закрепить в эксплуатации: при любом способе при запуске писать в журнал, «какой сертификат (отпечаток, срок) выбран». И для разбора сбоя, и для сверки с таблицей учёта работает эта одна строка.

8. Связь с сертификатом подписи кода — хранилище «Доверенные издатели»

До сих пор речь шла о сертификатах для обмена (TLS), но в хранилище сертификатов живёт ещё один мир — подпись кода. Точка касания — хранилище «Доверенные издатели (TrustedPublisher)» из таблицы 2.2: место, куда регистрируют сертификат издателя подписанного ПО как доверенный. Есть и в расположении пользователя, и в расположении компьютера,10 и используется в эксплуатации вроде распространения издателя внутреннего приложения через GPO в TrustedPublisher каждого ПК.

Если вы на стороне распространения приложения и нужно закрыть подпись кода и предупреждение SmartScreen («Windows защитил ваш компьютер»), это собрано в отдельной статье «Почему Windows показывает сообщение „Windows защитил ваш компьютер“». Знания этой статьи (два типа хранилища, распространение корня) остаются предпосылками как есть.

9. Итог

  • Хранилище сертификатов — два типа: пользователь (CurrentUser) и компьютер (LocalMachine). certmgr.msc / certlm.msc / диск Cert: — три способа посмотреть одно и то же. Первый шаг разбора — совместить, «о каком хранилище речь».
  • Куда помещать, решает учётная запись, от имени которой работает программа. Запуск без интерактивного пользователя (служба, IIS, задание) — хранилище компьютера; интерактивное приложение — хранилище пользователя, как правило.
  • «На разработке работало, в production не находится» — потому что хранилище пользователя разработчика и хранилище пользователя учётной записи службы разные. Приводят к хранилищу компьютера + StoreLocation.LocalMachine.
  • Размещение в хранилище компьютера и выдача права на чтение в «Управлении закрытыми ключами» всегда идут вместе. Не забудьте выдать заново при обновлении.
  • Импорт pfx по умолчанию неэкспортируемый. -Exportable — только когда действительно нужно. Хранение оригинала pfx и пароля тоже входит в проект.
  • Истечение срока предотвращают регулярной инвентаризацией Get-ChildItem Cert: ... -ExpiringInDays и таблицей учёта сертификатов. Замена — порядок «добавить → переключить → проверить → удалить», следите за пропуском обновления отпечатка в конфигурации.
  • Разбор цепочки — certutil -urlfetch -verify. Корень корпоративного CA распространяют через GPO/Intune; самоподписанный в корень — только среда проверки, со сроком.
  • В коде отпечаток выносят в конфигурацию и выбранный сертификат пишут в журнал. Одного этого достаточно, чтобы разбор сбоев из-за сертификатов стал другим.

Похожие статьи

Смежные области консультирования

KomuraSoft LLC занимается разработкой бизнес-приложений с интеграцией Web API по клиентскому сертификату (банковские API, онлайн-проверка страхового статуса и т. п.), разбором сбоев вида «сертификат не найден», «после обновления нет соединения» и наведением порядка в процедуре замены сертификатов. Можно начинать уже с этапа «непонятно, куда в хранилище смотреть».

Справочные ссылки

  1. Microsoft Learn, Local Machine and Current User Certificate Stores. О том, что хранилище сертификатов компьютера локально для ПК и общее для всех пользователей, живёт под HKEY_LOCAL_MACHINE; о том, что хранилище сертификатов пользователя своё на учётную запись и живёт под HKEY_CURRENT_USER; о том, что хранилище пользователя наследует содержимое хранилища компьютера, кроме хранилища «Личные» (сертификат, добавленный в «Доверенные корневые центры сертификации» компьютера, появляется и в одноимённом хранилище каждого пользователя). ↩ ↩2 ↩3 ↩4

  2. Microsoft Learn, System Store Locations. О положении в реестре CERT_SYSTEM_STORE_CURRENT_USER / CERT_SYSTEM_STORE_LOCAL_MACHINE (соответственно Software\Microsoft\SystemCertificates под HKEY_CURRENT_USER / HKEY_LOCAL_MACHINE); о предопределённых логических хранилищах MY, Root, Trust, CA; о том, что хранилище служб живёт в ключе реестра на имя службы (Software\Microsoft\Cryptography\Services\ServiceName\SystemCertificates); о том, что отдельно существуют хранилища для распространения групповой политикой. ↩ ↩2 ↩3 ↩4 ↩5

  3. Microsoft Learn, How to: View certificates with the MMC snap-in. О том, что certlm.msc управляет сертификатами локального устройства (локального компьютера), certmgr.msc — сертификатами текущего пользователя; о трёх видах цели оснастки сертификатов: «учётная запись компьютера», «учётная запись пользователя», «учётная запись службы»; о том, что пользователь без прав администратора может управлять только сертификатами своей учётной записи пользователя. ↩ ↩2 ↩3 ↩4

  4. Microsoft Learn, about_Certificate_Provider. О том, что диск PowerShell Cert: — иерархическое пространство имён с двумя расположениями хранилища CurrentUser и LocalMachine; о перечислении хранилищ и сертификатов через Get-ChildItem; о том, что параметр -ExpiringInDays возвращает сертификаты, истекающие в пределах заданного числа дней (0 — уже истёкшие); о динамических параметрах вроде -CodeSigningCert; о том, что срок действия хранится в свойстве NotAfter; о том, что сертификаты идентифицируются отпечатком. ↩ ↩2 ↩3 ↩4 ↩5 ↩6

  5. Microsoft Learn, How to Modify Private Key Permissions to Support Management Server or Streaming Server. О порядке открыть «Управление закрытыми ключами» (Manage Private Keys) в оснастке сертификатов с целью хранилища локального компьютера и на вкладке «Безопасность» добавить учётной записи выполнения службы (например Network Service) разрешение «Чтение». ↩ ↩2 ↩3

  6. Microsoft Learn, Import-PfxCertificate. О том, что Import-PfxCertificate принимает сертификат и закрытый ключ из файла PFX в указанное хранилище; о том, что без переключателя -Exportable принятый закрытый ключ экспортировать нельзя; о синтаксисе и примерах параметров -CertStoreLocation, -Password, -FilePath. ↩ ↩2 ↩3

  7. Microsoft Learn, certutil. О том, что certutil -verify проверяет сертификат, CRL и цепочку сертификатов и, если файл сертификата CA не задан, строит полную цепочку и проверяет её; о доступности параметра -urlfetch; о том, что certutil -store дампит хранилище сертификатов, а параметр -user обращается к хранилищу пользователя вместо хранилища компьютера. ↩ ↩2

  8. Microsoft Learn, Distribute Certificates to Client Computers by Using Group Policy. О порядке импорта сертификата в «Доверенные корневые центры сертификации» в Конфигурация компьютера\Политики\Конфигурация Windows\Параметры безопасности\Политики открытого ключа групповой политики и распространения клиентским компьютерам в домене; о нужных правах (уровень Domain Admins / Enterprise Admins). ↩

  9. Microsoft Learn, Create trusted certificate profiles in Microsoft Intune. О том, что профиль Intune «Доверенный сертификат» распространяет корневой или промежуточный сертификат CA на управляемые устройства; о том, что он используется для установления доверия к корневому CA как предпосылка профилей сертификатов SCEP/PKCS; о том, что в Windows можно выбрать целевое хранилище: «хранилище сертификатов компьютера — корень», «хранилище сертификатов компьютера — промежуточные», «хранилище сертификатов пользователя — промежуточные». ↩

  10. Microsoft Learn, X509Store Class. О том, что X509Store строится с указанием StoreName и StoreLocation (CurrentUser / LocalMachine), открывается методом Open и OpenFlags (ReadOnly, OpenExistingOnly и др.), коллекцию сертификатов получают свойством Certificates; о том, что в стандартные имена хранилищ входят My, Root, CA, TrustedPublisher и др. и хранилище TrustedPublisher есть и в CurrentUser, и в LocalMachine. ↩ ↩2

  11. Microsoft Learn, X509Certificate2Collection.Find(X509FindType, Object, Boolean) Method. О том, что метод Find ищет сертификаты по X509FindType (FindByThumbprint и др.) и значению поиска; о том, что при true в третьем аргументе validOnly возвращаются только действительные сертификаты, прошедшие проверку. ↩ ↩2

  12. Microsoft Learn, HttpClientHandler.ClientCertificates Property. О том, что свойство ClientCertificates — X509CertificateCollection, предъявляемая серверу при аутентификации клиента по сертификату; о том, что в .NET Core при наличии у сертификата атрибута Key Usage нужно включать «Digital Signature». ↩ ↩2

Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.

Политика аудита безопасности Windows и расследование журнала событий на практике — как стать ИТ-службой, которая умеет читать 4625

Практическое руководство, чтобы ответить на просьбу «посмотрите журналы неудачных входов». Разбирает связь базовой и расширенной политики...

Эти страницы показывают тему статьи в более широком контексте услуг и решений.

Статья напрямую связана со следующими услугами.

Частые вопросы

Вопросы, которые часто возникают при консультациях по теме статьи.

Чем отличаются certmgr.msc и certlm.msc?
Они открывают разные хранилища. certmgr.msc открывает хранилище сертификатов пользователя, под которым выполнен вход (текущий пользователь, CurrentUser); certlm.msc — хранилище сертификатов компьютера (локальный компьютер, LocalMachine). Хранилище компьютера общее для всех пользователей и служб на этом ПК; для управления нужны права администратора. Пользователь без прав администратора может управлять только своим хранилищем пользователя. Внутри обоих содержимое разделено на логические хранилища вроде «Личные» и «Доверенные корневые центры сертификации»; из PowerShell та же структура видна как Cert:\CurrentUser и Cert:\LocalMachine.
Куда помещать клиентский сертификат — в хранилище пользователя или компьютера?
Это решает учётная запись, от имени которой работает программа. Для настольного приложения, которое запускает интерактивный пользователь, базовый выбор — хранилище пользователя того, кто им пользуется (Cert:\CurrentUser\My). Для программы без интерактивного пользователя — службы Windows, пула приложений IIS, Планировщика заданий — помещайте сертификат в хранилище компьютера (Cert:\LocalMachine\My) и выдайте учётной записи выполнения право читать закрытый ключ. Хранилище пользователя у каждой учётной записи своё, поэтому сертификат, который разработчик импортировал в своё хранилище пользователя, службе под другой учётной записью невидим. Это типичная причина сбоя «на разработке работало, в production сертификат не находится».
Что проверять, если служба Windows не находит сертификат или не может им воспользоваться?
Проверка в два шага. Сначала — какое хранилище смотрит код. Если он открывает StoreLocation.CurrentUser, это хранилище пользователя учётной записи службы, а не то, которое администратор видит в certmgr.msc у себя. Перенесите сертификат в хранилище компьютера и приведите код к StoreLocation.LocalMachine. Затем — читается ли закрытый ключ. Быть в списке сертификатов и мочь пользоваться ключом — разные вещи: к закрытому ключу в хранилище компьютера по умолчанию обычно имеют доступ только администраторы и SYSTEM. В certlm.msc откройте «Управление закрытыми ключами» у нужного сертификата и выдайте «Чтение» учётной записи службы (NETWORK SERVICE и т. п.).
Как заранее находить истекающие сертификаты через PowerShell?
Инвентаризировать можно Get-ChildItem по диску Cert:. Например, Get-ChildItem Cert:\LocalMachine\My | Sort-Object NotAfter | Format-Table Thumbprint, Subject, NotAfter выводит хранилище «Личные» компьютера в порядке срока действия. Параметр -ExpiringInDays отбирает только сертификаты, которые истекают в пределах заданного числа дней; 0 возвращает уже истёкшие. Запускайте это ежемесячно по всем серверам и сверяйте результат с таблицей учёта сертификатов — и почти все сбои вида «с утра понедельника нет соединения, потому что сертификат истёк» исчезают.

Об авторе

Страница с профилем автора статьи.

Го Комура

Представитель KomuraSoft LLC

Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.

Публичные ссылки

Вернуться в блог