Автоматическая подпись кода-защита закрытого ключа
Я хочу автоматизировать подписание кода некоторых артефактов развертывания ClickOnce-исполняемых файлов и манифестов приложений. Для этого я использую signtool. В попытке сделать закрытый ключ доступным для подписания и при этом защитить файл сертификата, содержащий закрытый ключ (.pfx-файл), мой план состоит в том, чтобы установить сертификат в хранилище сертификатов локальной машины с неэкспортируемым ключом. (Я знаю, что есть способы экспорта ключа, даже если он помечен не подлежит экспорту.) Машина представляет собой сервер непрерывной интеграции,который будет доступен для избранных. Я надеялся настроить его таким образом, чтобы каждый раз, когда потребуется использовать закрытый ключ, он требовал ввода пароля закрытого ключа. Затем я бы настроил автоматическое задание (используя Jenkins ), которое потребовало бы параметра сборки, который собирал бы пароль закрытого ключа. Плагин Mask Passwords будет использоваться для маскировки пароля при вводе и в вывод на консоль.
Тем не менее, я наткнулся на пару дорожных заграждений. Прежде всего, несмотря на то, что существует "включить сильную защиту закрытого ключа. Если вы включите эту опцию, вам будет предложено использовать закрытый ключ каждый раз, когда приложение его использует."при импорте сертификата он кажется доступным только при импорте его в хранилище текущего пользователя, а не в хранилище локального компьютера. Во-вторых, даже если бы эта опция была доступна, инструмент signtool не предоставляет опции для установки пароль при подписании с использованием сертификата в магазине. Параметр password, '/p', применим только при использовании pfx-файла в качестве источника закрытого ключа (опция' /f'). Учитывая это, это не кажется жизнеспособным вариантом. Примечание: даже если " включить надежную защиту закрытого ключа."доступно для сертификатов в машинном хранилище, мое тестирование показывает, что при попытке использовать сертификат с включенным параметром просто появляется диалоговое окно с запросом разрешения на его использование, которое, очевидно, не будет работать для автоматизированной работы. Я изначально думал, что "подсказка" означает, что он попросит пароль.Еще один вариант, который я рассматривал, - это создание списков управления доступом для защиты закрытого ключа в хранилище сертификатов. Это можно сделать, щелкнув правой кнопкой мыши на сертификате и выбрав все задачи... / Управление Закрытыми Ключами... диалог. Это позволит ограничить использование закрытого ключа только теми, кто имеет на это право. (Примечание: когда пользователь без прав доступа к закрытому ключу пытается использовать его для подписи, он получает сообщение " Ошибка SignTool: не найдено сертификатов, удовлетворяющих всем заданным критериям.") Однако я не хочу предоставлять доступ к учетным данным, используемым службой сборки Дженкинса, потому что тогда любое задание сборки сможет подписать код. Я мог бы создать задание, которое выполняло бы сценарий для запуска команды подписи от имени конкретного пользователя. Для этого потребуется ввести имя пользователя домена и пароль в качестве параметров сборки. Я мог бы сделать это с помощью плагина Jenkins Mask Passwords. Мне это не очень нравится. это, однако, потому, что мне неудобно, что пароли масок являются достаточной защитой от раскрытия учетных данных домена, которые, если их скомпрометировать, дадут доступ к гораздо большему, чем просто закрытый ключ.
Если я откажусь от своей первоначальной идеи хранения сертификата в машинном хранилище, есть возможность поместить файл сертификата pfx в защищенную папку ACL на машине сборки, на которую имеют разрешения только процесс сборки и подписывающие пользователи. Это позволило бы мне сделать это. создайте задание сборки для использования содержащегося закрытого ключа, не предоставляя файл другим пользователям, имеющим доступ к машине. Чтобы использовать закрытый ключ, параметры сборки должны будут собрать пароль закрытого ключа.
Наконец, есть возможность использовать смарт-карту для хранения сертификата, но мы решили отказаться от этого.
Итак, мой вопрос заключается в том, существуют ли какие-либо другие способы сделать это, которые 1) защищают закрытый ключ от копирования, 2) предотвращают копирование закрытого ключа. используется неавторизованными пользователями для подписи кода и 3), учитывая, что пароль закрытого ключа предоставляется авторизованным пользователем, делает закрытый ключ для подписи службой сборки?
3 ответа:
Прежде всего я постараюсь ответить на ваши вопросы отдельно:
Я согласен, что требование взаимодействия с пользователем может быть не совсем удобным для службы автоматической сборки, но вам, вероятно, придется выбирать между безопасным решением с взаимодействием с пользователем и менее безопасным решением без взаимодействия с пользователем.
- защищает закрытый ключ от копирования:
только криптографическое оборудование (смарт-карта или hsm) может действительно защитить ключ от копирования. Хранилище сертификатов Windows (даже с неэкспортируемым параметром, как вы правильно отметили) или файл PKCS#12 (PFX) обеспечивают только ложное чувство защиты.- предотвращает использование закрытого ключа неавторизованными пользователями для подписи кода.:
ИМО для этого требуется взаимодействие с пользователем, например ввод пароля или PIN-кода. Если вы передадите пароль в качестве параметра, всегда есть вероятность, что другие процессы смогут получить его, например, из информации о процессе, журналов и т.д.- учитывая, что пароль закрытого ключа предоставляется авторизованным пользователем, делает закрытый ключ для подписи службой сборки:
криптографическое оборудование (смарт-карта или hsm), доступное через CSP (хранилище сертификатов windows) с интерактивно введенным PIN-кодом, должно работать с signtool без каких-либо проблем.Удобное, но менее безопасное решение № 1: Мне кажется, что вы уже нашли приемлемое решение, потому что вы не предоставили ни одного из его вариантов. ущерб.
Если я откажусь от своей первоначальной идеи хранения сертификата в машинном хранилище, есть возможность поместить файл сертификата pfx в защищенную папку ACL на машине сборки, на которую имеют разрешения только процесс сборки и подписывающие пользователи. Это позволило бы мне создать задание сборки для использования содержащегося закрытого ключа, не открывая файл другим пользователям, имеющим доступ к машине. Чтобы использовать закрытый ключ, параметры сборки должны соберите пароль закрытого ключа.
Однако обратите внимание, что pfx-файл может быть скопирован незаметно не только из живой системы, но и из резервных копий.
Удобное, но менее безопасное решение № 2 : хранить закрытый ключ на смарт-карте, не требующей ввода PIN-кода, и разрешать доступ к системе только доверенным пользователям. Это гарантировало бы, что ваш закрытый ключ не может быть скопирован, в то время как он оставался бы легко доступным для signtool. Однако это было бы вероятно требуется иметь два отдельных сервера сборки-один без смарт-карты, доступной для всех пользователей, и один со смарт-картой, доступной только для доверенных пользователей.
Неудобное безопасное решение : хранить закрытый ключ на смарт-карте, которая требует ввода PIN-кода и требует взаимодействия с пользователем (ввода PIN-кода) в процессе сборки.
Вы также можете рассмотреть возможность подписания сборок разработки с самозаверяющим сертификатом codesigning в автоматическом режиме и подписи сборки public release с доверенным сертификатом codesigning в ручном режиме.
Единственный оставшийся вариант, который я вижу, - это использовать HSM.
Вы можете создать закрытый ключ, защищенный картой оператора/набором карт (например, Thales имеет такой тип HSM). Набор карт оператора может быть установлен с кворумом, который определяет, сколько операторов должны вставить карту, прежде чем закрытый ключ может быть использован приложением, которое запросило использование этого закрытого ключа. Фалес также провайдер, который поддерживает эту функцию.
Проблема может заключаться в том, что CSP вызовет окно для отображения пользователя что карта должна быть вставлена (и опционально пароль к этой карте введен). Эта проблема может быть решена при запуске сервера сборки под какой-либо учетной записью пользователя с рабочим столом, в который можно войти. Когда вы входите в систему как этот пользователь и запускаете сервер сборки, он должен запросить использование закрытого ключа (например, подписав какой-то фиктивный файл или что-то еще). Всплывут окна, и операторы (столько, сколько требуется кворуму) будут один за другим вставлять свои карты и по желанию вводить свои пароли. После того, как все необходимые карты будут вставлены, ключ будет использоваться вашим сервером сборки. Любое другое приложение (возможно, запущенное другим пользователем) будет проходить ту же процедуру, чтобы использовать этот ключ. Если ваш сервер сборки аварийно завершает работу (происходит ли сбой серверов сборки? ) вы пройдете через ту же процедуру.
HSM также имеют защиту от несанкционированного доступа, поэтому закрытый ключ находится там в безопасности IMHO. Извините, что говорю только о Thales HSM, но у меня лично нет опыта работы с другими HSM.
Похоже, что полагаться на защищенный паролем PFX-файл, а не на хранилище сертификатов, безопасно. Даже без защиты ACL на папке жесткого диска, где находится PFX, никто из тех, кто берет файл PFX, не может использовать его для подписи чего-либо, если у них также нет пароля.
Затем настройте параметризованное задание Дженкинса "подпись" на этом компьютере, которое полностью инкапсулирует pfx-пароль, чтобы никто не мог его увидеть. (Я обдумываю какой-то сценарий, может быть, Powershell, преобразован в черный ящик EXE.) Уполномоченный Дженкинс Джобс может подключиться к работе подписи, чтобы выполнить подпись. EXE-файл будет регистрироваться каждый раз, когда он используется, как функция аудита. Просто нужно выяснить, как предотвратить несанкционированное использование задания подписи...должен же быть способ сделать это?