Как выгрузить неэкспортируемый закрытый ключ

Управление неэкспортируемым закрытым ключом

Добрый день! Уважаемые читатели и гости IT блога Pyatilistnik. В прошлый раз я вас научил и показал, как можно выгрузить сертификат пользователя в Active Directory, если это необходимо и какие права для этого нужны. Сегодня у нас речь пойдет также про сертификаты, а именно я поделюсь опытом, как я выгружаю неэкспортируемый закрытый ключ у SSL сертификата. Думаю, что данные действия будут вам весьма полезны, например, когда нужно мигрировать пользовательский профиль с Windows 10 на Windows 11.

Что такое неэкспортируемый закрытый ключ

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

Вот несколько ключевых моментов о неэкспортируемых закрытых ключах:

  1. Безопасность: Неэкспортируемые закрытые ключи обеспечивают дополнительный уровень безопасности, так как они не могут быть случайно или намеренно скопированы и использованы в другом месте. Это защищает от потенциальных угроз, связанных с компрометацией ключа.
  2. Использование в аппаратных модулях безопасности (HSM): Часто неэкспортируемые ключи хранятся в аппаратных модулях безопасности, которые предназначены для защиты криптографических ключей и выполнения криптографических операций. В таких случаях закрытый ключ никогда не покидает защищённое устройство.
  3. Процессы генерации: При создании неэкспортируемого закрытого ключа обычно используется специальный флаг или параметр, который указывает на то, что ключ не должен быть экспортируемым.
  4. Применение: Неэкспортируемые закрытые ключи часто используются в сценариях, где безопасность является критически важной, например, в банковских системах, системах управления идентификацией и аутентификацией, а также в других приложениях, требующих высокой степени защиты данных.

Как запретить экспорт закрытого ключа с рутокен

Как узнать, что у вас неэкспортируемый закрытый ключ

Самый простой метод определить, может ли ваш закрытый ключ быть экспортируемый или нет, это зайти в оснастку сертификаты:

Напомню, что для пользователей можно открыть certmgr.msc, а вот для просмотра сертификатов компьютера, уже в mmc добавлять соответствующую оснастку

Для примера я покажу сертификаты пользователя. У меня есть сертификат *.pyatilistnik.org, если открыть у него контекстное меню и выбрать "Все задачи - Экспорт"

certmgr.msc просмотр сертификатов

У вас откроется мастер экспорта сертификата, на втором шаге вы можете увидеть две опции:

  • Да, экспортировать закрытый ключ - у меня она как раз и неактивная
  • Нет, не экспортировать закрытый ключ

Мастер экспорта сертификата

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

dir cert:\LocalMachine\My

В моем примере 3 сертификата, нужный мне имеет Thumbprint FBB890310870522A267F642553D362460D508433.

Powershell просмотр сертификатов пользователя

Далее берем мой небольшой скрипт

# Задайте отпечаток сертификата
$thumbprint = "FBB890310870522A267F642553D362460D508433"

# Получите сертификат по отпечатку
$cert = Get-Item "cert:\LocalMachine\My\$thumbprint"

# Проверьте, можно ли экспортировать ключ
if ($cert.HasPrivateKey) {
$privateKey = $cert.PrivateKey
$exportable = $privateKey.CspKeyContainerInfo.Exportable

if ($exportable) {
Write-Output "Сертификат с отпечатком $thumbprint можно экспортировать."
} else {
Write-Output "Сертификат с отпечатком $thumbprint нельзя экспортировать."
}
} else {
Write-Output "Сертификат с отпечатком $thumbprint не содержит закрытого ключа."
}

В PowerShell, когда вы обращаетесь к свойству Exportable объекта CspKeyContainerInfo, это свойство указывает, можно ли экспортировать закрытый ключ сертификата.

  • privateKey: Это объект, представляющий закрытый ключ сертификата.
  • CspKeyContainerInfo: Это свойство объекта закрытого ключа, которое предоставляет информацию о контейнере ключей.
  • Exportable: Это логическое свойство, которое возвращает true, если закрытый ключ можно экспортировать, и false, если нет.

Таким образом, если privateKey.CspKeyContainerInfo.Exportable возвращает true, это означает, что вы можете экспортировать закрытый ключ вместе с сертификатом. Если возвращает false, то экспорт невозможен. Можно узнать и через KeyTool, но мне лень писать.

Powershell проверка возможности экспорта закрытого ключа у сертификата

Как сделать закрытый ключ экспортируемым

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

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

Распаковываем архив jailbreak-master, его состав выглядит вот так:

  • jbcert32.bat и jbcert64.bat - Для выключения опции "Да, экспортировать закрытый ключ", далее можно будет в mmc в интеративном режиме произвести экспорт
  • jbcsp32.bat и jbcsp64.bat - экспортирует ключи, которые содержатся в CSP и не связаны с сертификатом. jbscp требует .NET Framework 2.0.
  • jbstore32.bat и jbstore64.bat - позволяют экспортировать все сертификаты с закрытыми ключами из хранилища пользователя "MY", можно выполнять отдельно, как для пользователя, так и для компьютера.

Состав jailbreak-master

Открываем командную строку в режиме администратора и переходим в расположение с утилитой:

cd C:\temp\jailbreak-master
jbcert64.bat (так как у меня Windows 11 64-х битная)

как скопировать неэкспортируемый закрытый ключ

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

Включение экспорта неэкспортируемого закрытого ключа

Интересное наблюдение, что если вы закроете оснастку и заново откроете, сертификат вновь станет неэкспортируемым

Если запускать jbcsp32.bat и jbcsp64.bat, то там синтаксис такой:

jbscp.bat "Key container" "имя экспортируемого файла" [-u]

u — необязательный параметр, который будет экспортировать данные из пользовательского хранилища, а не из компьютера.

Если использовать jbstore32.bat и jbstore64.bat, то тут команды можно выполнить так. Если просто запускать батник, то он экспортирует все сертификаты в хранилище пользователя "MY". Дополнительные ключи:

  • -l - показывает все сертификаты
  • -a  - Создает дамп всех сертификатов
  • -1  - Делает дамп нужного сертификата

Запуск jbstore64.bat

Давайте посмотрим для примера мой состав сертификатов в расположении пользователя, для этого пишем:

jbstore2_64.exe -l -s "USER" (Если располагаетесь в каталоге jailbreak-master\binaries>) или jbstore64.bat -l -s "USER" (Если в каталоге с bat файлом)

Обратите внимание, что для точечного копирования неэкспортируемого контейнера закрытого ключа, вам нужно будет указывать "Subject Name".

Просмотр сертификатов в jbstore

Обратите внимание, что у меня у одного сертификата нет "Subject Name", это повлияет на то, когда я захочу использовать ключ -a, чтобы выгрузить все сертификаты, я буду получить ошибку:

Error sizing blob: -2146893813 This is because jbstore2 is not working, Are you using jailbreak32/64 to launch it? If there are still problems please contact iSEC Partners. Поэтому тут лучше воспользоваться первым битником

Error sizing blob -2146893813 This is because jbstore2 is not working

Давайте экспортируем сертификат Subject Name: *.pyatilistnik.org. Для этого я выполню такую команду:

jbstore64.bat -1 -n "*.pyatilistnik.org"

Успешно получил неэкспортируемый закрытый ключ

jbstore64.bat -1 -n "*.pyatilistnik.org" -o "pyatilistnik.org.pfx"

Можно добавить ключ -o и указать точное имя у копируемого сертификата с закрытым ключом. Далее вы просто можете скопировать контейнер закрытого ключа на флешку, перенести его на другой компьютер и установить, либо на текущим переустановить ОС и заново его добавить. Всегда полезно держать так резервную копию на всякий случай.

скопировать контейнер закрытого ключа на флешку

Как экспортировать неэкспортируемый закрытый ключ с помощью утилиты exportrsa

Если у вас не получилось произвести копирование сертификата первым методом, то можно попробовать использовать утилиту exportrsa. У меня в компьютере все так же остался закрытый электронный ключ в сертификате *.pyatilistnik.org, который я попытаюсь вытащить вторым методом. Загрузите утилиту.

Обязательно установите себе 32-х битную версию vcredist_x86_2010.exe в противном случае будите получать ошибку:

Не удается продолжить выполнение кода, поскольку система не обнаружила msvcr100d.dll. Для устранения этой проблемы попробуйте переустановить программу

 

Чтобы вам не искать по разным сайтам vcredist_x86_2010.exe, установите ее через официальный репозиторий Winget

msvcr100d.dll

Если все подготовлено, то в cmd запущенном в режиме администратора перейдите в расположение исполняемого файла exportrsa.exe и выполните команду:

exportrsa.exe

Код анализирует все хранилища системных ключей и экспортирует в файлы .pxf все, у которых имеется доступный закрытый ключ RSA. Если утилита exportrsa.exe может экспортировать сертификат с закрытым ключом, то она попросит вас указать два раза пароль, можно пропустить, а так же покажет какой сертификат она выгрузила в папку с исполняемым файлом и под каким именем. В моем примере сертификат "*.pyatilistnik.org" был выгружен в "1.pfx".

Копирование неэкспортируемого SSL через exportrsa.exe

Если exportrsa.exe не может скопировать закрытый ключ у экспортируемого сертификата, то вы получите ошибку:

Private key for cert "*.pyatilistnik.org" is not exportable: 8009000b Do you really want to export Public/private key for cert "*.pyatilistnik.org" [Y|N] (default N) >>>> y Cert "*.pyatilistnik.org" will be NOT exported

Private key for cert is not exportable 8009000b

Копирование неэкспортируемого контейнера закрытого ключа из реестра Windows

Выше я вам показывал, что вы можете посмотреть Thumbprint сертификата с помощью PowerShell:

  • dir cert:\LocalMachine\My - Смотрим для хранилища сертификатов компьютера
  • dir cert:\CurrentUser\My - Смотрим для хранилища сертификатов пользователя

напоминаю мне интересен Thumbprint FBB890310870522A267F642553D362460D508433

Просмотр Thumbprint для выгрузки сертификата из реестра

Сертификаты в реестре хранятся в разных местах, но нас будут интересовать два:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates\My\Certificates\
HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates\Root\Certificates\
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\SystemCertificates\MY\Certificates\
HKEY_USERS\SID-пользователя\Software\Microsoft\SystemCertificates\Root\Certificates\

Переходим в нужные ветки и экспортируем их.

Экспорт ветки реестра с сертификатами

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

Для удобства я воспользуюсь своим скриптом по экспорту веток реестра:

# Путь к папке для экспорта и узнаем SID пользователя
$exportPath = "C:\Cert\"
$sid = (New-Object System.Security.Principal.NTAccount($userName)).Translate([System.Security.Principal.SecurityIdentifier]).Value

# Убедитесь, что папка существует
if (-Not (Test-Path $exportPath)) {
New-Item -Path $exportPath -ItemType Directory
}

# Определите пути для экспорта
$registryPaths = @(
"HKCU\Software\Microsoft\SystemCertificates\Root\Certificates\FBB890310870522A267F642553D362460D508433",
"HKLM\SOFTWARE\Microsoft\SystemCertificates\MY\Certificates\FBB890310870522A267F642553D362460D508433",
"HKLM\SOFTWARE\WOW6432Node\Microsoft\SystemCertificates\MY\Certificates\FBB890310870522A267F642553D362460D508433",
"HKEY_USERS\$sid\Software\Microsoft\SystemCertificates\Root\Certificates\FBB890310870522A267F642553D362460D508433"
)

# Экспортируйте каждый путь
foreach ($path in $registryPaths) {
$fileName = [System.IO.Path]::Combine($exportPath, ($path -replace '[\\:]', '_') + ".reg")
reg export $path $fileName /y
}

На выходе вы получите 4 экспортированных файла.

Экспорт всех веток реестра с сертификатами закрытого ключа

Надеюсь, что у меня получилось объяснить вам как скопировать неэкспортируемый закрытый ключ и вы легко это сможете повторить. С вами был Иван Сёмин, автор и создатель IT портала Pyatilistnik.org.

Дополнительные ссылки

  • https://github.com/iSECPartners/jailbreak
  • https://github.com/luipir/ExportNotExportablePrivateKey/tree/master
Оцените статью
Настройка серверов windows и linux
Добавить комментарий