Самоподписанные сертификаты подписи кода для MSIX: Практическое руководство
2026-06-02
Tags: Windows · Microsoft Store · MSIX · Подводные камни Store
В предыдущей статье мы прошли полный процесс предварительного тестирования MSIX-пакетов перед отправкой в Store. Один из шагов, который неоднократно всплывал, — работа с самоподписанными сертификатами: установка в хранилище Доверенные лица, упаковка с правильным сертификатом и так далее. Но в той статье мы обошли стороной важный вопрос: как на самом деле создать такой сертификат?
Это руководство охватывает всё, что нужно знать о самоподписанных сертификатах подписи кода для MSIX-пакетов: создание, экспорт, использование в Visual Studio и управление ими в команде.
Зачем MSIX нужна подпись
MSIX-пакеты должны быть подписаны цифровой подписью перед установкой. Это не опционально — даже для боковой загрузки (sideloading) и локального тестирования операционная система требует действительную подпись на каждом файле .msix.
Для распространения через Store корпорация Microsoft подписывает ваш пакет собственным сертификатом после сертификации. Но для локального тестирования и боковой загрузки вам нужен собственный сертификат. Здесь и приходят на помощь самоподписанные сертификаты: они позволяют подписывать пакеты для разработки и тестирования без покупки коммерческого сертификата подписи кода.
Процесс подписания служит двум целям:
- Целостность: гарантирует, что пакет не был изменён после подписания
- Идентификация: определяет издателя (вас) — CN (Common Name) в сертификате должен совпадать со значением
<Publisher>в вашемPackage.appxmanifest
Использование New-SelfSignedCertificate
В состав Windows входит командлет PowerShell New-SelfSignedCertificate, который может генерировать сертификаты для тестирования. Откройте PowerShell от имени администратора и попробуйте следующее:
New-SelfSignedCertificate -Type Custom -Subject "CN=YourCompany" -KeyUsage DigitalSignature -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") -CertStoreLocation "Cert:\CurrentUser\My"Разберём каждый параметр:
| Параметр | Назначение |
|---|---|
-Type Custom | Создаёт пользовательский сертификат, а не базовый |
-Subject "CN=YourCompany" | Задаёт Common Name — должно совпадать с издателем вашего приложения в Package.appxmanifest |
-KeyUsage DigitalSignature | Помечает сертификат для использования цифровой подписи |
-TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") | Расширенное использование ключа — Code Signing (1.3.6.1.5.5.7.3.3), а также Basic Constraints — End Entity (2.5.29.19) — требуется механизмом развёртывания Windows для пакетов приложений |
-CertStoreLocation "Cert:\CurrentUser\My" | Сохраняет сертификат в личном хранилище текущего пользователя |
Без обоих значений TextExtension сертификат может быть распознан не полностью — OID Basic Constraints помечает его как конечную сущность (End Entity, не ЦС), что проверяет механизм развёртывания Windows при проверке MSIX-пакетов. Отсутствие этого параметра может вызывать ошибки развёртывания или предупреждения WACK в некоторых сборках Windows.
Примечание: В своих проектах я использовал самоподписанные сертификаты без расширения Basic Constraints, и они работали без проблем. Это ограничение является рекомендованной Microsoft лучшей практикой, но не является строгим требованием для разработки и боковой загрузки.
Создание сертификата с EKU подписи кода
Если вы уже создали сертификат без EKU подписи кода, вы всё ещё можете проверить, обладает ли он нужными свойствами. Откройте сертификат (через certlm.msc) и проверьте Details → Enhanced Key Usage — там должно быть указано Code Signing.
Вот практический скрипт, который создаёт сертификат и подготавливает его для использования с MSIX:
# Создание самоподписанного сертификата подписи кода (Code Signing EKU + Basic Constraints)
$cert = New-SelfSignedCertificate -Type Custom -Subject "CN=YourCompany" -KeyUsage DigitalSignature -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}") -CertStoreLocation "Cert:\CurrentUser\My"
# Отображение сведений о сертификате
$cert | Format-List Subject, Thumbprint, NotAfter
# Вывод отпечатка для быстрой ссылки
Write-Host "Certificate thumbprint: $($cert.Thumbprint)"Замените "CN=YourCompany" на фактическое имя издателя. Имя издателя можно найти в Package.appxmanifest в элементе Identity:
<Identity Name="YourApp" Publisher="CN=YourCompany" Version="1.0.0.0" />Экспорт PFX и CER
После создания сертификата обычно требуются файлы двух типов:
PFX (Personal Information Exchange)
Содержит закрытый ключ + сертификат. Это то, что использует Visual Studio для подписи пакетов. Относитесь к нему как к паролю — любой, у кого есть доступ к PFX, может подписывать пакеты от вашего имени.
$password = ConvertTo-SecureString -String "YourPassword" -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath "codesign.pfx" -Password $passwordCER (Certificate file)
Содержит только открытый сертификат (без закрытого ключа). Это то, что вы распространяете на тестовые машины, чтобы они могли доверять вашим подписанным пакетам.
Export-Certificate -Cert $cert -FilePath "codesign.cer"Краткая справка
| Формат | Содержит закрытый ключ? | Использование |
|---|---|---|
.pfx | Да | Подпись пакетов (Visual Studio, signtool) |
.cer | Нет | Установка на тестовых машинах для установления доверия |
Импорт сертификата и проверка отпечатка
Чтобы установить MSIX-пакеты, подписанные вашим самоподписанным сертификатом, на тестовой машине, сертификат должен быть доверенным для системы.
Установка сертификата
- Дважды щёлкните файл
.cer→ Install Certificate - Выберите Local Machine → Browse → выберите Доверенные лица
- Завершите работу мастера
Также через PowerShell:
Import-Certificate -FilePath "codesign.cer" -CertStoreLocation "Cert:\LocalMachine\TrustedPeople"Поиск отпечатка
Отпечаток (thumbprint) понадобится при использовании инструментов командной строки для подписи:
# Список всех сертификатов подписи кода в личном хранилище
Get-ChildItem -Path "Cert:\CurrentUser\My" -CodeSigningCert | Format-Table Subject, Thumbprint, NotAfterОтпечаток — это 40-символьная шестнадцатеричная строка. Скопируйте её точно — она понадобится для команд подписи.
Использование сертификата в Visual Studio
Когда у вас есть PFX-файл, вы можете использовать его в мастере упаковки Visual Studio:
- Щёлкните правой кнопкой по проекту → Package and Publish → создайте новый профиль упаковки
- На шаге Select Signing Certificate нажмите Select from File...
- Укажите путь к вашему файлу
.pfxи введите пароль - Завершите работу мастера упаковки
Сертификат сохраняется в профиле упаковки, поэтому не нужно выбирать его заново каждый раз. Однако если сертификат истечёт или вы перейдёте на новый, потребуется обновить профиль.
Использование сертификата из хранилища сертификатов
Если вы импортировали PFX в личное хранилище сертификатов, его можно выбрать напрямую:
- На шаге выбора сертификата раскройте выпадающий список вместо нажатия "Select from File..."
- Найдите свой сертификат в списке (определяется по указанному вами CN)
- Выберите его и продолжайте
Этот подход удобен, но будьте внимательны — Visual Studio может кешировать конкретный отпечаток, и если сертификат будет обновлён (новая пара ключей), сохранённая ссылка может стать недействительной.
Истечение срока действия, обновление и переподписание сертификата
Самоподписанные сертификаты, созданные с помощью New-SelfSignedCertificate, по умолчанию действуют 1 год (в некоторых версиях по умолчанию 3 года — проверьте свойство NotAfter).
Контрольный список
- [ ] Запишите дату истечения срока действия сертификата
- [ ] До истечения срока создайте новый сертификат и переподпишите все пакеты
- [ ] Распространите новый файл
.cerна тестовые машины - [ ] Обновите профиль упаковки в Visual Studio
- [ ] Для отправки в Store создайте новый тестовый пакет с новым сертификатом
Для проверки срока действия:
Get-ChildItem -Path "Cert:\CurrentUser\My" -CodeSigningCert | Format-Table Subject, NotAfterПри обновлении создайте новый сертификат с тем же CN, экспортируйте новые PFX/CER и переподпишите пакеты. Отпечаток изменится, поэтому убедитесь, что все ссылки обновлены.
Советы для командной разработки
Когда несколько разработчиков должны подписывать пакеты одним и тем же сертификатом:
- Храните PFX в защищённом общем месте — парольный архив в командном хранилище или менеджере паролей, поддерживающем вложения файлов
- Никогда не помещайте PFX в систему контроля версий — добавьте
*.pfxв ваш.gitignore - Документируйте пароль в командном менеджере паролей, а не в коде или документах
- Каждый разработчик импортирует PFX в своё личное хранилище сертификатов, а затем выбирает его в Visual Studio
- Используйте один и тот же CN для всех сертификатов, если нужно создавать индивидуальные сертификаты для разработчиков (для сборок, не предназначенных для публикации)
Для конвейеров CI/CD большинство агентов сборки поддерживают импорт PFX через защищённые переменные окружения или секреты — обратитесь к документации вашей CI-платформы за рекомендуемым подходом.
Эта статья — дополнительный материал к серии Подводные камни Store.