Задачи подписывания кода
Эта глава дает процедуры и примеры для процесса подписывания кода. Это покрывает то, что необходимо сделать, прежде чем Вы начнете подписывать код, как подписать код, и как поставить код, который Вы подписали.
Получение идентификационных данных подписания
Для подписания кода Вам нужны идентификационные данные подписывания кода, которые являются закрытым ключом плюс цифровой сертификат. Цифровой сертификат должен иметь расширение использования, позволяющее ему использоваться для подписания, и он должен содержать открытый ключ, соответствующий закрытому ключу. Можно использовать больше чем одни идентификационные данные подписания, каждого в его собственной цели, такой как один, чтобы использоваться для бета семян и один для заключительных, выпущенных продуктов. Однако большинство организаций использует только одни идентификационные данные.
Можно получить два типа сертификатов от Apple с помощью портала разработчика: Разработчик сертификаты ID (для общедоступного распределения) и сертификаты распределения (для представления App Store Mac). Для узнавания больше об этом считайте Руководство по Потоку операций Инструментов для Mac.
Если у Вас нет существующих идентификационных данных, необходимо сначала создать тот с помощью Ассистента Сертификата, который предоставлен как часть приложения Доступа Цепочки для ключей. Этот инструмент создает открытый ключ, помещает его в Вашу цепочку для ключей, и дополнительно может произвести сертификат, подписав запрос, который можно тогда отправить в Apple (или другой центр сертификации). Центр сертификации тогда отправляет Вам сертификат, в сочетании с Вашим закрытым ключом, завершающий Ваши цифровые идентификационные данные.
В Доступе Цепочки для ключей (доступный в/Applications/Utilities), выберите File> Import Items.
Выберите целевую цепочку для ключей для идентификационных данных.
Выберите файл сертификата.
Нажмите Open.
Прежде чем Вы получите идентификационные данные подписывания кода и подпишете Ваш код, рассмотрите следующие моменты:
Не поставляйте приложения, подписанные самоподписанными сертификатами. Самоподписанный сертификат, создаваемый с Ассистентом Сертификата, не распознан операционными системами пользователей как допустимый сертификат ни в какой цели кроме проверки определяемого требования Вашего кода со знаком. Поскольку самоподписанный сертификат не был подписан признанным корневым центром сертификации, пользователь может только проверить, что две версии Вашего приложения прибыли из того же источника; они не могут проверить, что Ваша компания является истинным источником кода. Для получения дополнительной информации о корневых полномочиях, посмотрите Понятия Безопасности.
В зависимости от внутренних политик Вашей компании Вам, возможно, придется включить Сборку и Интеграцию Вашей компании, Юридические, и Маркетинговые отделы в решениях о том, какие идентификационные данные подписания для использования и как получить его. Необходимо запустить этот процесс заранее времени, необходимо фактически подписать код для распределения клиентам.
Любая подписанная версия Вашего кода, входящего в руки пользователей, будет казаться, была подтверждена Вашей компанией для использования. Поэтому Вы не могли бы хотеть использовать свои «заключительные» идентификационные данные подписания для подписания кода, который находится все еще в разработке.
Идентификационные данные подписания, независимо от того как полученный, полностью поставились под угрозу, если это когда-нибудь вне физической проверки того, кто бы ни является имеющим полномочия ставить подпись код. Это означает, что закрытый ключ идентификационных данных подписания никогда не должен, ни при каких обстоятельствах, быть данным конечным пользователям, и должен быть ограничен одним или небольшим количеством доверяемых лиц в Вашей компании. Прежде, чем получить идентификационные данные подписания и продолжение для подписания кода необходимо определить, кто в компании будет обладать идентификационными данными, кто может использовать его, и как это будет бережно храниться. Например, если идентификационные данные должны использоваться больше чем одним лицом, можно сохранить их в цепочке для ключей безопасного компьютера и дать пароль цепочки для ключей только авторизованным пользователям, или можно поместить идентификационные данные на смарт-карту, на которую только у авторизованных пользователей есть PIN.
Самоподписанный сертификат, создаваемый Ассистентом Сертификата, достаточен для внутреннего тестирования и разработки, независимо от того, какие процедуры Вы устанавливаете для подписания выпущенных продуктов.
Открытые приложения> Утилиты> Доступ Цепочки для ключей.
Из меню Keychain Access выберите Certificate Assistant> Create a Certificate.
Заполните имя для сертификата. Это имя появляется в утилите Keychain Access как имя сертификата.
Выбрать
Self Signed Root
отType
всплывающее меню.Проверьте
Let me override defaults
флажок. ЩелкнутьContinue
.Укажите порядковый номер для сертификата. Любое число сделает, пока у Вас нет никакого другого сертификата с тем же именем и порядковым номером.
Выбрать
Code Signing
отCertificate Type
всплывающее меню. ЩелкнутьContinue
.Заполните информацию для сертификата. Щелкнуть
Continue
.Примите значения по умолчанию для остальной части диалоговых окон.
Добавление Info.plist к однофайловым инструментам
Как обсуждено в Требованиях Кода, система часто использует Info.plist
файл комплекта приложений для определения определяемого требования кода. Несмотря на то, что однофайловые инструменты обычно не имеют Info.plist
, можно добавить тот. Для этого используйте следующую процедуру:
Добавьте
Info.plist
файл к Вашему проекту (включая добавление его к Вашему управлению исходным кодом).Удостоверьтесь
Info.plist
файл имеет следующие ключи:CFBundleIdentifier
CFBundleName
Значение для
CFBundleIdentifier
используется в качестве уникального имени по умолчанию Вашей программы в целях Подписывания кода. ПосколькуCFBundleIdentifier
значение также используется, когда Ваши ресурсы доступов к приложениям в комплекте приложений, может иногда быть необходимо использовать групповоеCFBundleIdentifier
значение для помощника. Если Вы делаете это, необходимо обеспечить различный, уникальный идентификатор в целях подписывания кода путем передачи-i
или--identifier
отметьте кcodesign
команда.Идентификатор, используемый для подписания, должен быть глобально уникальным. Для обеспечения уникальности необходимо включать имя компании в значение. Обычная форма для этого идентификатора является иерархическим именем в обратной нотации DNS, начиная с высокоуровневого домена, сопровождаемого названием компании, сопровождаемым организацией в компании, и заканчивающийся названием продукта. Например,
CFBundleIdentifier
значение дляcodesign
командаcom.apple.security.codesign
.Значение для
CFBundleName
обнаруживается в системных диалоговых окнах как имя Вашей программы, таким образом, это должно соответствовать Ваше маркетинговое имя для продукта.Добавьте следующие параметры своим флагам компоновщика:
-sectcreate __TEXT __info_plist
Информация plist_pathгде Информация plist_path является полным путем
Info.plist
файл в Вашем проекте.В XCode, например, Вы добавили бы эти флаги компоновщика к
OTHER_LDFLAGS
создайте переменную (Другие Флаги Компоновщика в правилах сборки цели).
Например, вот содержание Info.plist
файл для codesign
команда:
<plist version="1.0"> |
<dict> |
<key>CFBundleDevelopmentRegion</key> |
<string>English</string> |
<key>CFBundleIdentifier</key> |
<string>com.apple.security.codesign</string> |
<key>CFBundleInfoDictionaryVersion</key> |
<string>6.0</string> |
<key>CFBundleName</key> |
<string>codesign</string> |
<key>CFBundleVersion</key> |
<string>0.3</string> |
</dict> |
</plist> |
Подписание Вашего кода
Вы используете codesign
команда для подписания кода. В этом разделе рассматриваются, что подписать и дает некоторые примеры использования codesign
. Посмотрите codesign(1)
страница руководства для полного описания ее использования.
Что подписаться
Необходимо подписать каждую исполнимую программу в продукте, включая приложения, инструменты, скрытые инструменты помощника, утилиты и т.д. Подписание комплекта приложений покрывает свои ресурсы, но не свои субкомпоненты, такие как инструменты и подпакеты. Каждый из них должен быть подписан независимо.
Если Ваше приложение состоит из большого UI, расстаются с одним или более небольшими инструментами помощника, пытающимися представить единственную поверхность пользователю, можно сделать их неразличимыми к подписыванию кода путем предоставления им всем того же самого идентификатора подписывания кода. (Можно сделать это путем проверки, что у них всех есть то же CFBundleIdentifier
значение в их Info.plist
, или при помощи -i
опция в codesign
команда, для присвоения того же идентификатора.) В этом случае все Ваши компоненты программы имеют доступ к тем же элементам цепочки для ключей и проверяют как та же программа. Сделайте это, только если включенные программы действительно предназначены для формирования единственного объекта без сделанных различий.
Универсальному двоичному файлу (пакет или инструмент) автоматически применились к отдельным подписям каждый компонент архитектуры. Они независимы, и обычно только собственная архитектура в системе конечного пользователя проверяется.
В случае пакетов установщика (.pkg и пакеты .mpkg), все неявно подписывается: архив CPIO, содержащий полезную нагрузку, архив CPIO, содержащий сценарии установки и ведомость материалов (BOM), каждому записали хеш в заголовке XAR и том заголовке поочередно, подписывается. Поэтому при изменении сценария установки (например) после того, как пакет был подписан, подпись будет недопустима.
Можно также хотеть подписать плагины и библиотеки. Несмотря на то, что это в настоящее время не требуется, это будет в будущем, и нет никакого недостатка к наличию подписей на этих компонентах.
В зависимости от ситуации, codesign
может добавить к Вашему Мужественному исполняемому файлу, добавить расширенные атрибуты к нему или создать новые файлы в каталоге Contents Вашего пакета. Ни один из Ваших других файлов не изменяется.
Когда подписаться
Можно работать codesign
в любое время в любой системе рабочий OS X v10.5 или позже, если у Вас есть доступ к идентификационным данным подписания. Можно выполнить его от фазы сценария оболочки в XCode, если Вам нравится, или как шаг в Ваших сценариях Make-файла, или где-либо еще Вы считаете подходящими. Подписание обычно делается как часть процесса освоения продукта, после того, как была выполнена работа обеспечения качества. Избегите подписывать предзаключительные копии своего продукта так, чтобы никто не мог перепутать пропущенный или случайно выпустил неполную версию Вашего продукта для реальной вещи.
Ваше заключительное подписание должно быть сделано после того, как Вы будете сделаны, создавая Ваш продукт, включая любую последующую обработку и блок ресурсов пакета. Подписывание кода обнаруживает любое изменение в Вашей программе после подписания, поэтому при внесении каких-либо изменений вообще после того, как подписание, код будет отклонен, когда попытка будет предпринята для проверки его. Подпишите свой код перед упаковкой продукта для поставки.
Поскольку каждый компонент архитектуры подписывается независимо, это в порядке для выполнения универсальных бинарных операций (таких как выполнение lipo
команда) на программах со знаком. Результат будет все еще законно подписан, пока Вы не вносите никакие другие изменения.
Используя Команду элемента кода
codesign
команда полностью описана в codesign(1)
страница руководства. Этот раздел обеспечивает некоторые примеры общего использования команды. Обратите внимание на то, что Ваши идентификационные данные подписания должны быть в цепочке для ключей для этих команд для работы.
Подписание кода
Подписать код расположилось в <code-path>
, использование идентификационных данных подписания <identity>
, используйте следующую команду:
codesign -s <identity> <code-path> … |
<code-path>
значение может быть папкой пакета или определенным двоичным файлом кода. Посмотрите, Что Расписаться за большее количество подробных данных.
Идентификационные данные можно назвать с любой (чувствительной к регистру) подстрокой атрибута общего названия сертификата, пока подстрока уникальна всюду по Вашим цепочкам для ключей. (Подписание идентификационных данных обсуждено в Получении Идентификационных данных Подписания.)
Как типично для команд Стиля Unix, эта команда не дает подтверждения успеха. Для получения некоторой обратной связи включайте -v
опция:
codesign -s <identity> -v <code-path> … |
Используйте -r
опция указать внутреннее требование. При использовании этой опции можно указать текстовый файл, содержащий требования, предварительно скомпилированный двоичный файл требований или фактический текст требования, снабженный префиксом знак «равно» (=
). Например, для добавления внутреннего требования, чтобы все библиотеки быть подписанными Apple, Вы могли использовать следующую опцию:
-r="library => anchor apple" |
Язык требования кода описан на Языке Требования Подписывания кода.
Если Вы создали свою собственную иерархию сертификата (возможно, использующий Ассистент Сертификата — видят Получение Идентификационных данных Подписания), и хотят использовать привязку Вашего сертификата для формирования определяемого требования для программы, Вы могли использовать следующую команду:
codesign -s signing-identity -r="designated => anchor /my/anchor/cert and identifier com.mycorp.myprog" |
Обратите внимание на то, что исходный язык требования принимает любого хеш SHA1 сертификата (например, H"abcd...."
) или путь к DER закодировал сертификат в файле. Это в настоящее время не принимает ссылку на сертификат в цепочке для ключей, таким образом, необходимо экспортировать сертификат прежде, чем выполнить эту команду.
Можно также использовать csreq
команда, чтобы выписать требования к файлу, и затем использовать путь к тому файлу как входное значение для -r
опция в codesign
команда. См. страницу руководства для csreq(1)
для получения дополнительной информации о той команде.
Вот некоторые другие выборки требований:
anchor apple
– код подписывается Appleanchor trusted
– привязке доверяет (для подписывания кода) системаcertificate leaf = /path/to/certificate
– лист (подписание) сертификат является указанным темcertificate leaf = /path/to/certificate and identifier "com.mycorp.myprog"
– листовой сертификат и идентификатор программы столь же указаныinfo[mykey] = myvalue
–Info.plist
ключmykey
существует и имеет значениеmyvalue
За исключением явного anchor trusted
требование, система не консультируется со своей доверительной базой данных настроек при проверке требования кода. Поэтому, пока Вы не добавляете это определяемое требование к своей подписи кода, сертификат привязки, который Вы используете для подписания Вашего кода, не должен быть представлен системе пользователя для проверки для следования.
Добавление прав для игры в песочнице
Если Вы хотите включить Тестовую среду приложения для приложения, необходимо добавить дающий право список свойств во время процесса подписания. Чтобы сделать это, добавьте --entitlements
флаг и надлежащий список свойств. Например:
codesign --entitlements /path/to/entitlements.plist -s <identity> <code-path> … |
Для списка дающих право ключей, которые могут появиться в дающем право списке свойств, посмотрите Дающую право Ключевую Ссылку.
Проверка кода
Для заверения подписи на двоичном файле со знаком используйте -v
опция без других опций:
codesign -v <code-path> … |
Это проверяет что двоичные файлы кода в <code-path>
фактически подписываются, что подпись допустима, что все изолированные компоненты неизменны, и что все это передает некоторые основные проверки непротиворечивости. Это не делает проверкой по умолчанию, что код удовлетворяет любые требования кроме своего собственного определяемого требования. Для проверки определенного требования используйте -R
опция. Например, чтобы проверить, что Почтовое приложение Apple идентифицируется как Почта, подписанная Apple, и защитило с корневым подписанием Apple сертификата, Вы могли использовать следующую команду:
codesign -v -R="identifier com.apple.mail and anchor apple" /Applications/Mail.app |
Обратите внимание на то, что, в отличие от этого -r
опция, -R
опция берет только единственное требование, а не набор требований (нет =>
теги). Добавьте один или несколько дополнительный -v
опции получить подробные данные о процессе проверки.
Если Вы передаете число, а не путь к проверять опции, codesign
берет число, чтобы быть процессом ID (изодромный с предварением) из рабочего процесса, и выполняет динамическую проверку вместо этого.
Получение информации о подписях кода
Для получения информации о подписи кода используйте -d
опция. Например, для вывода внутренних требований подписи кода к стандарту используйте следующую команду:
codesign -d -r code-path |
Обратите внимание на то, что эта опция не заверяет подпись.
Используя spctl Инструмент к Подписанию Тестового кода
spctl(8)
инструмент может использоваться для тестирования подписей кода против различных системных политик, что пользователь может установить. Базовый синтаксис для оценки подписывания кода показан ниже:
# Assess an application or tool |
spctl --assess --type execute myTool |
# Assess an installer package |
spctl --assess --type install myInstallerPackage.pkg |
Если Ваша подпись приложения или пакета допустима, эти инструменты выходят тихо со статусом выхода 0
. (Введите echo $?
вывести на экран статус выхода последней команды.), Если подпись недопустима, эти инструменты распечатывают сообщение об ошибке и выход с ненулевым статусом выхода.
Для более подробной информации о том, почему оценка перестала работать, можно добавить --verbose
флаг. Например:
spctl --assess --verbose=4 /bin/ls |
Это распечатывает следующий вывод:
/bin/ls: accepted |
source=Apple System |
Для наблюдения всего, система должна сказать об оценке, передать --raw
опция. С этим флагом, spctl
инструмент распечатывает подробную оценку как список свойств.
К whitelist программа (точно, как будто UI сделал это), введите:
spctl --add --label mytest /some/program |
- метка является дополнительным тегом, который можно добавить к собственным правилам. Этот тег позволяет Вам удалять правило легко путем ввода:
spctl --remove --label mytest |
Обратите внимание на то, что это удаляет все правила, соответствующие метку, что означает, что это - удобный способ очистить после тестирования. Можно также временно приостановить правила путем ввода:
spctl --disable --label mytest |
и повторно включите им позже путем ввода:
spctl --enable --label mytest |
Для наблюдения списка текущих правил оценки используйте --list
флаг. Например:
spctl --list --type execute |
Получающийся список правил мог бы быть похожим на это:
3[Apple System] P0 allow execute |
anchor apple |
4[Mac App Store] P0 allow execute |
anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] exists |
5[Developer ID] P0 allow execute |
anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] exists and certificate leaf[field.1.2.840.113635.100.6.1.13] exists |
7[UNLABELED] P0 allow execute [/var/tmp/firefly/RUN-FIREFLY-JOBS/test1.app] |
cdhash H"f34c03450da53c07ac69282089b68723327f278a" |
8[UNLABELED] P0 allow execute [/var/tmp/firefly/RUN-FIREFLY-JOBS/test1.app] |
identifier "org.tpatko.Run-Firefly-Job-X-Cores" and certificate root = H"5056a3983e3b7f44e17e3db8e483b35b6745b236" |
Заметьте, что список выше приводит много предопределенных правил, описывающих обработку определенных классов кода. Например, правило 5 получает все приложения, подписанные Разработчиком ID. Можно отключить те приложения путем ввода:
spctl --disable --label "Developer ID" |
Эта команда говорит системе больше не позволять выполнение любого Разработчика подписанные ID приложения, которые ранее не запустил пользователь. Это точно, что происходит, когда Вы используете предпочтение UI для переключения на «App Store Mac только».
Каждое правило в списке имеет уникальное число, которое может использоваться для обращения его. Например, если Вы вводите:
spctl --list --label "Developer ID" |
Вы могли бы получить список правил, который похож на это:
5[Developer ID] P0 allow execute |
anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] exists and certificate leaf[field.1.2.840.113635.100.6.1.13] exists |
6[Developer ID] P0 allow install |
anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] exists and certificate leaf[field.1.2.840.113635.100.6.1.14] exists |
Заметьте, что существуют отдельные правила для выполнения (5) и установка (6), и можно включить и отключить их отдельно. Например, для включения установки новых приложений подписало с Разработчиком ID, можно ввести:
spctl --enable --rule 6 |
Наконец, spctl
позволяет Вам включать или отключать подсистему политики оценки безопасности. По умолчанию оценка выключена, что означает, что без вести пропавшие или недопустимые подписи кода не препятствуют тому, чтобы запустилось приложение. Однако строго рекомендуется протестировать приложение с оценкой, позволенной гарантировать, что приложение работает правильно.
Чтобы включить или отключить оценку, дайте одну из следующих команд.
sudo spctl --master-enable # enables assessment |
sudo spctl --master-disable # disables assessment |
spctl --status # shows whether assessment is enabled |
Для получения дополнительной информации см. страницу руководства для spctl(8)
.
Поставка и обновление продукта
Единственная вещь, имеющая значение для системы подписывания кода, состоит в том, что код со знаком установил в системе пользователя, идентичной коду, который Вы подписали. Не имеет значения, как Вы упаковываете, поставляете или устанавливаете свой продукт, пока Вы не вводите изменений в продукт. Сжатие, кодирование, шифрование, и даже двоичный файл, исправляющий код, в порядке, пока Вы заканчиваете с точно, с чего Вы запустили. Можно использовать любой установщик, который Вы любите, пока он ничего не пишет в продукт, поскольку он устанавливает его. Перетаскивать-установки прекрасны также.
При квалификации новой версии продукта подпишите его, когда Вы подписали предыдущую версию с тем же идентификатором и тем же определяемым требованием. Система пользователя будет полагать, что новая версия Вашего продукта та же программа как предыдущая версия. В частности цепочка для ключей не отличит более старые и более новые версии Вашей программы и пока была подписана и пока уникальный идентификатор, не изменился.
Можно проявить подход частичного обновления к пересмотру кода системы пользователя. Для этого подпишите новую версию, как обычно, затем вычислите различия между новым и старыми подписанными версиями, и передайте различия. Поскольку различия включают новые данные подписи, результатом установки изменений в системе конечного пользователя будет недавно подписанная версия. Вы не можете исправить приложение со знаком в поле. Если Вы сделаете так, то система заметит, что приложение изменилось и лишит законной силы подпись, и нет никакого способа подтвердить или оставить приложение в поле.