Руководство по безопасности

CLI winapp упрощает локальную разработку под Windows: он может создать сертификат подписи, добавить его в доверенные на вашем компьютере и включить режим разработчика. Каждый из этих шагов изменяет состояние компьютера или создает файл, который содержит закрытый ключ, поэтому он помогает точно знать, что они делают.

Эта страница объясняет последствия каждой команды, как отменить ее и что делать по-разному при отправке. Сертификаты разработки и режим разработчика — это обычный, поддерживаемый путь для локального тестирования. Цель заключается в том, что вы понимаете, что вы выбираете, а не избегаете их.

Сертификаты разработки

Пакеты MSIX должны быть подписаны перед установкой Windows. Для локального тестирования winapp cert generate создает самоподписанный сертификат, чтобы вы могли подписать и установить собственный пакет, ничего не покупая.

Что winapp cert generate создает

Созданный сертификат — это самоподписанный сертификат конечного объекта для подписи кода:

Недвижимость Ценность
Key RSA, 2048 бит, помечен как экспортируемый
Алгоритм подписи SHA-256 с RSA (PKCS#1 v1.5)
Использование ключа Цифровая подпись
Расширенное использование ключей Подпись кода (1.3.6.1.5.5.7.3.3)
Основные ограничения Не центр сертификации
Обоснованность 365 дней по умолчанию (--valid-days)
Тема Должно соответствовать Publisher в манифесте

Команда записывает две вещи:

  • devcert.pfx в текущем каталоге (или в пути, который вы передаете в --output). Этот файл содержит как сертификат, так и его закрытый ключ.
  • Копия сертификата в личном хранилище сертификатов (Cert:\CurrentUser\My).

При использовании --export-cer он также записывает файл .cer рядом с .pfx. Этот файл содержит только открытый сертификат — нет закрытого ключа, что делает его правильным для передачи товарищу по команде или тестовому компьютеру, которому необходимо доверять сборкам.

Note

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

Пароль по умолчанию

winapp cert generate использует password в качестве пароля PFX, если не указан --password. То же значение по умолчанию применяется, когда впоследствии вы передаёте этот сертификат в winapp sign, где параметр пароля также имеет значение --password, и в winapp pack, куда передаётся --cert-password.

Известный пароль означает, что закрытый ключ devcert.pfx фактически незащищен — любой пользователь, получающий файл, может подписать с ним код. Это приемлемый компромисс для одноразового сертификата, который используется только для подписи локальных тестовых сборок на вашем компьютере, и именно поэтому этот вариант выбран по умолчанию.

Important

Обработайте пароль по умолчанию как сигнал о том, что сертификат является удаленным. Если сертификат когда-либо используется для подписи другого пользователя, он не должен быть сертификатом winapp cert generate с паролем по умолчанию — см. раздел "Подпись для рабочей среды".

Скрипты и агенты не должны сравнивать пароль самостоятельно: winapp cert generate --json сообщает "defaultPasswordIsPublic": true и повторяет раскрытие информации в warnings массиве всякий раз, когда используется значение по умолчанию. См. JSON-вывод команды cert generate.

Где находится файл сертификата

devcert.pfx — закрытый ключ на диске. Два правила уберегают её от неприятностей:

Не зафиксируйте его.winapp cert generate автоматически добавляет имя .gitignore файла сертификата рядом с ним, поэтому поток по умолчанию уже охватывается. Если вы перемещаете файл, переименовываете его или создаете его в каталог, управляемый другим .gitignore, убедитесь, что запись последовала за ней:

git check-ignore -v devcert.pfx

Если команда ничего не выводит, файл не игнорируется — добавьте его перед коммитом.

Не включайте его в пакет.winapp pack упаковывает всё, что находится во входном каталоге, поэтому devcert.pfx, находящийся в выходной папке приложения, в итоге попадает в поставляемый пакет MSIX. Создайте сертификат за пределами папки, как показано в руководстве по упаковке EXE/CLI , и убедитесь, что он отсутствует перед распространением:

# Unpack the package and check that no certificate is inside
winapp tool makeappx unpack /p .\MyApp.msix /d .\inspect /o
Get-ChildItem .\inspect -Recurse -Include *.pfx, *.cer

Tip

.pfx Если реальный закрытый ключ когда-либо получает фиксацию или публикацию, измените его: создайте новый сертификат, повторно войдите и остановите доверие к старому, выполнив действия по удалению доверенного сертификата. Удаление файла в более позднем коммите не удаляет его из истории.

Что предоставляет winapp cert install

winapp cert install добавляет сертификат в LocalMachine\TrustedPeople хранилище. Для этого требуются права администратора, так как оно изменяет доверие для каждого пользователя на компьютере.

Как только сертификат будет установлен в TrustedPeople, Windows будет считать любой пакет MSIX, подписанный этим сертификатом, достаточно доверенным для установки, а не только тот пакет, который вы тестировали. Для сертификата, закрытый ключ которого находится у вас и хранится локально, это именно тот эффект, который и предполагается. Вот почему к этому следует подходить осознанно:

  • Доверяйте сертификатам, которые вы создали сами или получили от того, кому вы бы разрешили устанавливать программное обеспечение на этом компьютере.
  • Не устанавливайте сертификат разработки на общих, производственных или рабочих компьютерах, на которые полагаются другие пользователи.
  • Предпочтительно распространять .cer (только открытый ключ), а не .pfx, если коллеге нужно установить ваш тестовый пакет. Они получают возможность доверять вашим сборкам, не получая при этом возможности подписывать от вашего имени.

Чтобы на другом тестовом компьютере доверять .cer, запустите winapp cert install непосредственно на нём — команда принимает либо .pfx, либо только открытый .cer:

# Run as Administrator
winapp cert install .\devcert.cer

Эквивалентен использованию только встроенных средств Windows:

# Run as Administrator
Import-Certificate -FilePath .\devcert.cer -CertStoreLocation Cert:\LocalMachine\TrustedPeople

Удаление доверенного сертификата

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

Сначала найдите отпечаток:

Get-ChildItem Cert:\LocalMachine\TrustedPeople |
    Where-Object { $_.Subject -like '*CN=Contoso*' } |
    Format-List Subject, Thumbprint, NotAfter

Затем удалите его из хранилища доверенных сертификатов компьютера. Для этого шага требуется повышение прав:

# Run as Administrator. Replace with the thumbprint from the previous command.
$thumbprint = 'ABCD...'
Remove-Item -Path "Cert:\LocalMachine\TrustedPeople\$thumbprint"

cert generate также поместил сертификат вместе с его закрытым ключом в ваше личное хранилище. Удалите это из обычной неповышенной командной строки, выполнив вход под той же учетной записью, из-под которой был запущен cert generate:

$thumbprint = 'ABCD...'
Remove-Item -Path "Cert:\CurrentUser\My\$thumbprint"

Important

Выполните две приведенные выше команды в указанных контекстах. Если вы используете другую учетную запись администратора, Cert:\CurrentUser в этом сеансе с повышенными привилегиями хранится хранилище администратора , а не ваше, поэтому закрытый ключ останется в хранилище создаваемого пользователя.

Наконец, удалите .pfx и все копии .cer, которые вы раздали, и отмените регистрацию пакетов, установленных вручную с его помощью:

winapp unregister

Note

Удаление сертификата не удаляет пакеты, которые уже были установлены с ним. Удалите их по отдельности через Параметры > Приложения > Установленные приложения или с помощью winapp unregister для пакетов, зарегистрированных в режиме разработки.

Режим разработчика

Для регистрации пакета приложения непосредственно из папки на диске — свободной структуры файлов — вместо установки собранного и подписанного MSIX-пакета в Windows требуется режим разработчика. Такие команды, как winapp run и create-debug-identity, зависят от этого и не работают без него, а winapp init предлагает включить это за вас.

Что изменится при включении

Интерфейс командной строки включает режим разработчика, записывая два значения DWORD в разделе HKEY_LOCAL_MACHINE:

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock
    AllowDevelopmentWithoutDevLicense = 1
    AllowAllTrustedApps               = 1

Так как это параметры на уровне компьютера, интерфейс командной строки запускает вспомогательный процесс с повышенными привилегиями и Windows отображает запрос управления учетными записями пользователей. Если вы отклоните запрос, ничего не изменится.

Практически это означает, что компьютер будет:

  • Зарегистрируйте пакеты приложений непосредственно из папки на диске, не упаковывая их в MSIX и вообще не подписывая (AllowDevelopmentWithoutDevLicense).
  • Устанавливайте пакеты приложений из источников вне Microsoft Store, если они подписаны сертификатом, которому доверяет компьютер, — в том числе любым сертификатом разработчика в TrustedPeople (AllowAllTrustedApps).

Important

Режим разработчика и доверенный сертификат разработки — это преднамеренное ослабление ограничений установки по умолчанию. Такое сочетание подходит только для компьютеров разработки и тестирования. Оставьте это отключённым на продуктивных системах, киосках и в инфраструктуре общего пользования.

Управление моментом включения

winapp init спрашивает перед тем, как что-либо изменить, а --use-defaults полностью пропускает этот вопрос, оставляя Developer Mode без изменений. Это делает запуски скриптов и CI безопасными по умолчанию:

winapp init --use-defaults

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

Отключение

Используйте систему > параметров > для разработчиков и отключите режим разработчика. Это рекомендуемый способ, поскольку раздел «Параметры» также очищает связанные данные о состоянии ОС. Чтобы затем проверить значение параметра реестра:

Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock' `
    -Name AllowDevelopmentWithoutDevLicense, AllowAllTrustedApps

Отключение режима разработчика не удаляет доверенные сертификаты или уже установленные пакеты— см. раздел "Удаление доверенного сертификата".

Подписывание для рабочей среды

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

Выберите идентификатор подписи

  • Azure Trusted Signing — облачная служба подписи. Закрытый ключ никогда не хранится на вашей машине сборки, поэтому нет .pfx, который нужно было бы защищать, допускать его утечку или вручную ротировать. Используйте winapp az-sign, который выполняет аутентификацию с помощью стандартной цепочки учетных данных Azure и работает с GitHub Actions OIDC или управляемой идентификационной записью.

    winapp az-sign .\MyApp.msix
    
  • Сертификат для подписи кода от доверенного центра сертификации — передайте его в winapp sign в качестве второго позиционного аргумента, указав пароль в --password. Затем вы несете ответственность за безопасное хранение ключевого материала; храните его в аппаратном токене, хранилище ключей или хранилище секретов вашего CI-провайдера и никогда — в репозитории.

  • Microsoft Store — если вы распространяете исключительно через Магазин, он подписывает пакет для вас и вам не нужно подписывать перед отправкой.

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

Храните секреты для подписи вне репозитория

Пароли сертификатов следует хранить в хранилище секретов CI, а не в конфигурационном файле. Считывайте их из переменных среды вместо того, чтобы жёстко прописывать их в коде:

winapp sign .\MyApp.msix $env:SIGNING_CERT_PATH --password $env:SIGNING_CERT_PASSWORD

То же самое относится к конфигурации сборки, проверенной в системе управления версиями, например конфигурации Electron Forge, см. в статье "Упаковка электронных данных". winapp az-sign полностью устраняет эту проблему, поскольку нет пароля, который нужно передавать.

Перед публикацией

Краткий контрольный список для перехода с локального тестирования на распространение:

  • Пакет подписан сертификатом, выданным центром сертификации, с помощью Azure Trusted Signing или отправлен в Магазин — но не с помощью devcert.pfx.
  • Ни файл .pfx, ни файл .cer не входит в состав пакета.
  • Пароль сертификата не отображается в зафиксированных файлах, скриптах сборки или журналах CI.
  • Субъект сертификата соответствует манифесту Publisher.
  • Сертификаты разработки и режим разработчика не включены на компьютерах, которые должны запускать приложение только.

Создание отчетов о проблеме безопасности

Чтобы сообщить об уязвимости безопасности в самом интерфейсе командной строки winapp, выполните процесс в SECURITY.md. Не создавайте публичные issue на GitHub для сообщений о проблемах безопасности.