Как выгрузить неэкспортируемый закрытый ключ
- Что такое неэкспортируемый закрытый ключ
- Как узнать, что у вас неэкспортируемый закрытый ключ
- Как сделать закрытый ключ экспортируемым
- Как экспортировать неэкспортируемый закрытый ключ с помощью утилиты exportrsa
- Копирование неэкспортируемого контейнера закрытого ключа из реестра Windows
- Дополнительные ссылки
Добрый день! Уважаемые читатели и гости IT блога Pyatilistnik. В прошлый раз я вас научил и показал, как можно выгрузить сертификат пользователя в Active Directory, если это необходимо и какие права для этого нужны. Сегодня у нас речь пойдет также про сертификаты, а именно я поделюсь опытом, как я выгружаю неэкспортируемый закрытый ключ у SSL сертификата. Думаю, что данные действия будут вам весьма полезны, например, когда нужно мигрировать пользовательский профиль с Windows 10 на Windows 11.
Что такое неэкспортируемый закрытый ключ
Неэкспортируемый закрытый ключ - это закрыты ключ, который был создан и сохранён таким образом, что его невозможно экспортировать или извлечь из хранилища ключей. Это означает, что закрытый ключ не может быть скопирован или передан в другие системы или приложения.
Вот несколько ключевых моментов о неэкспортируемых закрытых ключах:
- Безопасность: Неэкспортируемые закрытые ключи обеспечивают дополнительный уровень безопасности, так как они не могут быть случайно или намеренно скопированы и использованы в другом месте. Это защищает от потенциальных угроз, связанных с компрометацией ключа.
- Использование в аппаратных модулях безопасности (HSM): Часто неэкспортируемые ключи хранятся в аппаратных модулях безопасности, которые предназначены для защиты криптографических ключей и выполнения криптографических операций. В таких случаях закрытый ключ никогда не покидает защищённое устройство.
- Процессы генерации: При создании неэкспортируемого закрытого ключа обычно используется специальный флаг или параметр, который указывает на то, что ключ не должен быть экспортируемым.
- Применение: Неэкспортируемые закрытые ключи часто используются в сценариях, где безопасность является критически важной, например, в банковских системах, системах управления идентификацией и аутентификацией, а также в других приложениях, требующих высокой степени защиты данных.
Как узнать, что у вас неэкспортируемый закрытый ключ
Самый простой метод определить, может ли ваш закрытый ключ быть экспортируемый или нет, это зайти в оснастку сертификаты:
Напомню, что для пользователей можно открыть certmgr.msc, а вот для просмотра сертификатов компьютера, уже в mmc добавлять соответствующую оснастку
Для примера я покажу сертификаты пользователя. У меня есть сертификат *.pyatilistnik.org, если открыть у него контекстное меню и выбрать "Все задачи - Экспорт"
У вас откроется мастер экспорта сертификата, на втором шаге вы можете увидеть две опции:
- Да, экспортировать закрытый ключ - у меня она как раз и неактивная
- Нет, не экспортировать закрытый ключ
Все то же самое можно сделать и с помощью PowerShell. Откройте PowerShell ISE в режиме администратора и для начала посмотрите список всех сертификатов пользователя, нас будут интересовать их Thumbprint.
dir cert:\LocalMachine\My
В моем примере 3 сертификата, нужный мне имеет Thumbprint FBB890310870522A267F642553D362460D508433.
Далее берем мой небольшой скрипт
# Задайте отпечаток сертификата
$thumbprint = "FBB890310870522A267F642553D362460D508433"# Получите сертификат по отпечатку
$cert = Get-Item "cert:\LocalMachine\My\$thumbprint"# Проверьте, можно ли экспортировать ключ
if ($cert.HasPrivateKey) {
$privateKey = $cert.PrivateKey
$exportable = $privateKey.CspKeyContainerInfo.Exportableif ($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, но мне лень писать.
Как сделать закрытый ключ экспортируемым
Сразу оговорюсь, что показанные методы нужны исключительно для резервного копирования ваших сертификатов.
В поставленной перед нами задачей нам поможет набор библиотек jailbreak. Из требований у вас должны быть права локального администратора для этих действий.
Распаковываем архив jailbreak-master, его состав выглядит вот так:
- jbcert32.bat и jbcert64.bat - Для выключения опции "Да, экспортировать закрытый ключ", далее можно будет в mmc в интеративном режиме произвести экспорт
- jbcsp32.bat и jbcsp64.bat - экспортирует ключи, которые содержатся в CSP и не связаны с сертификатом. jbscp требует .NET Framework 2.0.
- jbstore32.bat и jbstore64.bat - позволяют экспортировать все сертификаты с закрытыми ключами из хранилища пользователя "MY", можно выполнять отдельно, как для пользователя, так и для компьютера.
Открываем командную строку в режиме администратора и переходим в расположение с утилитой:
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 - Делает дамп нужного сертификата
Давайте посмотрим для примера мой состав сертификатов в расположении пользователя, для этого пишем:
jbstore2_64.exe -l -s "USER" (Если располагаетесь в каталоге jailbreak-master\binaries>) или jbstore64.bat -l -s "USER" (Если в каталоге с bat файлом)
Обратите внимание, что для точечного копирования неэкспортируемого контейнера закрытого ключа, вам нужно будет указывать "Subject Name".
Обратите внимание, что у меня у одного сертификата нет "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. Поэтому тут лучше воспользоваться первым битником
Давайте экспортируем сертификат 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
Если все подготовлено, то в cmd запущенном в режиме администратора перейдите в расположение исполняемого файла exportrsa.exe и выполните команду:
exportrsa.exe
Код анализирует все хранилища системных ключей и экспортирует в файлы .pxf все, у которых имеется доступный закрытый ключ RSA. Если утилита exportrsa.exe может экспортировать сертификат с закрытым ключом, то она попросит вас указать два раза пароль, можно пропустить, а так же покажет какой сертификат она выгрузила в папку с исполняемым файлом и под каким именем. В моем примере сертификат "*.pyatilistnik.org" был выгружен в "1.pfx".
Если 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
Копирование неэкспортируемого контейнера закрытого ключа из реестра Windows
Выше я вам показывал, что вы можете посмотреть Thumbprint сертификата с помощью PowerShell:
- dir cert:\LocalMachine\My - Смотрим для хранилища сертификатов компьютера
- dir cert:\CurrentUser\My - Смотрим для хранилища сертификатов пользователя
напоминаю мне интересен Thumbprint FBB890310870522A267F642553D362460D508433
Сертификаты в реестре хранятся в разных местах, но нас будут интересовать два:
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