
Введение
В корпоративной среде с ростом количества сотрудников, которым требуется доступ к системам с использованием ЭЦП, возникла необходимость автоматизировать процесс установки сертификатов.
Попытки применить стандартные средства — Import-PfxCertificate, certutil и другие — результата не дали: сертификаты не виделись рядом приложений, включая СБИС. Готовых рабочих решений тоже не нашлось. Пришлось разрабатывать собственный метод.
В этой статье описан механизм, применяемый для распространения сертификатов ИФНС. Методы экспорта ключей и сертификатов можно найти в сети, поэтому они здесь не рассматриваются. Вопросы безопасности при передаче приватных ключей также остаются за рамками — предполагается, что всё выполняется во внутреннем доверенном контуре.
За основу была взята статья «Перенос контейнеров закрытых ключей и сертификатов CryptoPro», где описан ручной процесс. Я доработал его и автоматизировал для централизованного распространения через GPO.
Проблема
При переносе сертификатов и ключей между машинами или профилями возникает одна и та же трудность: они «привязаны» к SID пользователя.
Если импортировать .reg напрямую, записи окажутся связаны с SID другого пользователя и работать не будут.
Поэтому при автоматическом распространении необходимо корректно подставлять текущий SID.
Решение
Я подготовил набор PowerShell-скриптов, которые выполняются от имени пользователя при логоне (через GPO Logon Script).
Сценарий работы такой:
-
Шаблон реестра
В исходном.regфайле хранится конфигурация с «старым» SID. -
Подмена SID
Скрипт получает SID текущего пользователя[System.Security.Principal.WindowsIdentity]::GetCurrent().User.Valueи заменяет им статический идентификатор в файле.
-
Импорт реестра
Обновлённый.regфайл импортируется в HKCU. -
Копирование сертификатов
Из сетевой папки (\\share\Cert\My) копируются нужные файлы в профиль пользователя:%APPDATA%\Microsoft\SystemCertificates\My -
Готово
При следующем запуске приложений (Outlook, браузеры, CryptoPro) пользователь сразу получает доступ к сертификатам.
Пример кода
Запуск разных скриптов по группам
Этот пример показывает, как можно привязывать разные сценарии к членству пользователя в группах AD. Каждое группа соответствует отдельному сертификату.
# Задаем группы и соответствующие пути к скриптам для каждой группы $groupScriptMap = @{ "First Group" = "\\path\first_script.ps1" "Second Group" = "\\path\second_script.ps1" } # Получаем информацию о текущем пользователе $user = [System.Security.Principal.WindowsIdentity]::GetCurrent() $userGroups = $user.Groups | ForEach-Object { $_.Translate([System.Security.Principal.NTAccount]).Value.Split("\")[1] } # Перебираем каждую группу из маппинга и проверяем, состоит ли в ней пользователь foreach ($group in $groupScriptMap.Keys) { if ($userGroups -contains $group) { Write-Output "Пользователь $($user.Name) принадлежит группе $group." # Получаем путь к скрипту для этой группы $scriptPath = $groupScriptMap[$group] Write-Output "Запускается скрипт для группы: $scriptPath" # Выполняем соответствующий скрипт try { #Start-Process -FilePath "powershell.exe" -ArgumentList "-ExecutionPolicy Bypass -File $scriptPath" -NoNewWindow -Wait Start-Process -FilePath "powershell.exe" -ArgumentList "-ExecutionPolicy", "Bypass", "-File", "`"$scriptPath`"" -NoNewWindow -Wait } catch { Write-Output "Ошибка при выполнении скрипта для группы $[group]: $_" } } else { Write-Output "Пользователь $($user.Name) не состоит в группе $group." } }
Данные скрипт производит основные действия по замене SID, импорте reg файла и копировании хранилища личных сертификатов пользователя
# Указываем путь к файлу реестра (исходный шаблон .reg файл) $regFileSource = "\\path\first_file.reg" # Определяем временную папку текущего пользователя $tempFolder = [System.IO.Path]::GetTempPath() # Определяем SID текущего пользователя $userSID = (Get-WmiObject -Class Win32_UserAccount -Filter "Name='$env:USERNAME'").SID # Определяем целевой файл во временной папке $regFileTemp = Join-Path $tempFolder "modified_registry.reg" # Читаем содержимое исходного файла реестра $regContent = Get-Content -Path $regFileSource -Encoding Unicode # Статический SID, который будем заменять $oldSID = "S-1-5-21-3734670798-76392145-1373982661-1117" # Заменяем статический SID на SID текущего пользователя $updatedContent = $regContent -replace $oldSID, $userSID # Записываем обновленный файл реестра во временную папку $updatedContent | Out-File -FilePath $regFileTemp -Encoding Unicode # Импортируем обновленный файл реестра reg import $regFileTemp # Указываем сетевую папку для копирования $networkFolder = "\\path\My" # Папка пользователя, куда нужно скопировать сетевую папку $userFolder = "C:\Users\$env:USERNAME\AppData\Roaming\Microsoft\SystemCertificates" # Копируем содержимое с заменой конфликтов Copy-Item -Path $networkFolder -Destination $userFolder -Recurse -Force Write-Host "Файл реестра был успешно импортирован, и папка скопирована."
Варианты использования
-
Распространение сертификатов ЭЦП среди сотрудников
-
Миграция рабочих мест и перенос профилей
Репозиторий
Исходный код доступен здесь. Там же постарался создать подробный и понятный README.
👉 GitHub — provision_of_certificates_GPO
Заключение
Предложенный метод позволяет автоматизировать раздачу сертификатов через GPO без ручных действий. Он прост в реализации.
При этом стоит помнить о недостатках:
-
нет централизованного контроля за сроком действия сертификатов;
-
приватные ключи передаются в файлах, что требует доверенной среды;
-
метод рассчитан именно на Windows-среду с CryptoPro.
ссылка на оригинал статьи https://habr.com/ru/articles/941198/
Добавить комментарий