Задачи подписывания кода

Эта глава дает процедуры и примеры для процесса подписывания кода. Это покрывает то, что необходимо сделать, прежде чем Вы начнете подписывать код, как подписать код, и как поставить код, который Вы подписали.

Получение идентификационных данных подписания

Для подписания кода Вам нужны идентификационные данные подписывания кода, которые являются закрытым ключом плюс цифровой сертификат. Цифровой сертификат должен иметь расширение использования, позволяющее ему использоваться для подписания, и он должен содержать открытый ключ, соответствующий закрытому ключу. Можно использовать больше чем одни идентификационные данные подписания, каждого в его собственной цели, такой как один, чтобы использоваться для бета семян и один для заключительных, выпущенных продуктов. Однако большинство организаций использует только одни идентификационные данные.

Можно получить два типа сертификатов от Apple с помощью портала разработчика: Разработчик сертификаты ID (для общедоступного распределения) и сертификаты распределения (для представления App Store Mac). Для узнавания больше об этом считайте Руководство по Потоку операций Инструментов для Mac.

Если у Вас нет существующих идентификационных данных, необходимо сначала создать тот с помощью Ассистента Сертификата, который предоставлен как часть приложения Доступа Цепочки для ключей. Этот инструмент создает открытый ключ, помещает его в Вашу цепочку для ключей, и дополнительно может произвести сертификат, подписав запрос, который можно тогда отправить в Apple (или другой центр сертификации). Центр сертификации тогда отправляет Вам сертификат, в сочетании с Вашим закрытым ключом, завершающий Ваши цифровые идентификационные данные.

bullet
Импортировать сертификат подписания с Доступом Цепочки для ключей
  1. В Доступе Цепочки для ключей (доступный в/Applications/Utilities), выберите File> Import Items.

  2. Выберите целевую цепочку для ключей для идентификационных данных.

  3. Выберите файл сертификата.

  4. Нажмите Open.

Прежде чем Вы получите идентификационные данные подписывания кода и подпишете Ваш код, рассмотрите следующие моменты:

bullet
Использовать Ассистент Сертификата для создания самоподписанных идентификационных данных подписания
  1. Открытые приложения> Утилиты> Доступ Цепочки для ключей.

  2. Из меню Keychain Access выберите Certificate Assistant> Create a Certificate.

    ../Art/create_cert1.jpg
  3. Заполните имя для сертификата. Это имя появляется в утилите Keychain Access как имя сертификата.

  4. Выбрать Self Signed Root от Type всплывающее меню.

  5. Проверьте Let me override defaults флажок. Щелкнуть Continue.

    ../Art/create_cert2.jpg
  6. Укажите порядковый номер для сертификата. Любое число сделает, пока у Вас нет никакого другого сертификата с тем же именем и порядковым номером.

  7. Выбрать Code Signing от Certificate Type всплывающее меню. Щелкнуть Continue.

    ../Art/create_cert3.jpg
  8. Заполните информацию для сертификата. Щелкнуть Continue.

  9. Примите значения по умолчанию для остальной части диалоговых окон.

Добавление Info.plist к однофайловым инструментам

Как обсуждено в Требованиях Кода, система часто использует Info.plist файл комплекта приложений для определения определяемого требования кода. Несмотря на то, что однофайловые инструменты обычно не имеют Info.plist, можно добавить тот. Для этого используйте следующую процедуру:

  1. Добавьте Info.plist файл к Вашему проекту (включая добавление его к Вашему управлению исходным кодом).

  2. Удостоверьтесь Info.plist файл имеет следующие ключи:

    • CFBundleIdentifier

    • CFBundleName

  3. Значение для CFBundleIdentifier используется в качестве уникального имени по умолчанию Вашей программы в целях Подписывания кода. Поскольку CFBundleIdentifier значение также используется, когда Ваши ресурсы доступов к приложениям в комплекте приложений, может иногда быть необходимо использовать групповое CFBundleIdentifier значение для помощника. Если Вы делаете это, необходимо обеспечить различный, уникальный идентификатор в целях подписывания кода путем передачи -i или --identifier отметьте к codesign команда.

    Идентификатор, используемый для подписания, должен быть глобально уникальным. Для обеспечения уникальности необходимо включать имя компании в значение. Обычная форма для этого идентификатора является иерархическим именем в обратной нотации DNS, начиная с высокоуровневого домена, сопровождаемого названием компании, сопровождаемым организацией в компании, и заканчивающийся названием продукта. Например, CFBundleIdentifier значение для codesign команда com.apple.security.codesign.

  4. Значение для CFBundleName обнаруживается в системных диалоговых окнах как имя Вашей программы, таким образом, это должно соответствовать Ваше маркетинговое имя для продукта.

  5. Добавьте следующие параметры своим флагам компоновщика:

    -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 – код подписывается Apple

  • anchor trusted – привязке доверяет (для подписывания кода) система

  • certificate leaf = /path/to/certificate – лист (подписание) сертификат является указанным тем

  • certificate leaf = /path/to/certificate and identifier "com.mycorp.myprog" – листовой сертификат и идентификатор программы столь же указаны

  • info[mykey] = myvalueInfo.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).

Поставка и обновление продукта

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

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

Можно проявить подход частичного обновления к пересмотру кода системы пользователя. Для этого подпишите новую версию, как обычно, затем вычислите различия между новым и старыми подписанными версиями, и передайте различия. Поскольку различия включают новые данные подписи, результатом установки изменений в системе конечного пользователя будет недавно подписанная версия. Вы не можете исправить приложение со знаком в поле. Если Вы сделаете так, то система заметит, что приложение изменилось и лишит законной силы подпись, и нет никакого способа подтвердить или оставить приложение в поле.