Обзор подписывания кода
Подписывание кода является методом безопасности, который может использоваться, чтобы гарантировать целостность кода, определить, кто разработал часть кода, и определить цели, в которых разработчик предназначил часть кода, который будет использоваться. Несмотря на то, что система подписывания кода выполняет проверки политики на основе подписи кода, это до вызывающей стороны для создания стратегических решений на основе результатов тех проверок. То, когда это - операционная система, осуществляющая проверки политики, позволят ли Вашему коду работать в данной ситуации, зависит от того, подписали ли Вы код, и от требований Вы включали в подпись.
В этой главе описываются преимущества подписания кода и представляет некоторые фундаментальные понятия, которые необходимо понять для выполнения процесса подписывания кода.
Перед чтением этой главы необходимо быть знакомы с понятиями, описанными в Обзоре безопасности.
Преимущества подписания кода
Когда часть кода была подписана, возможно определить надежно, был ли код изменен кем-то другим, чем подписывающее лицо. Система может обнаружить такое чередование, было ли это намеренным (злонамеренным атакующим, например) или случайным (как тогда, когда файл повреждается). Кроме того, посредством подписания, разработчик может утвердить, что обновление приложения допустимо и должно быть рассмотрено системой как то же приложение как предыдущая версия.
Например, предположите, что пользователь дает разрешение приложения SurfWriter получать доступ к элементу цепочки для ключей. Каждый раз, когда SurfWriter пытается получить доступ к тому элементу, система должна определить, является ли это действительно тем же приложением, запрашивающим доступ. Если приложение подписывается, система может идентифицировать приложение с уверенностью. Если разработчик обновляет приложение и подписывает новую версию с тем же уникальным идентификатором, система распознает обновление как то же приложение и предоставляет ему доступ, не запрашивая проверку от пользователя. С другой стороны, если SurfWriter повреждается или взламывается, подпись больше не соответствует предыдущую подпись; система обнаруживает изменение и отказывает в доступе к элементу цепочки для ключей.
Точно так же при использовании Родительского контроля, чтобы препятствовать тому, чтобы дочерний элемент выполнил определенную игру, и та игра была подписана ее производителем, дочерний элемент не может обойти управление путем переименования или движущиеся файлы. Родительский контроль использует подпись для однозначной идентификации игры независимо от ее имени, расположения или номера версии.
Все виды кода могут быть подписаны, включая инструменты, приложения, сценарии, библиотеки, плагины и другие «подобные коду» данные.
Подписывание кода имеет три отличных цели. Это может привыкнуть к:
гарантируйте, что не была изменена часть кода
идентифицируйте код как прибывающий из определенного источника (разработчик или подписывающее лицо)
определите, защищен ли код в определенной цели (например, для доступа к элементу цепочки для ключей).
Чтобы позволить подписанному коду выполнить эти цели, подпись кода состоит из трех частей:
Изоляция, которая является набором контрольных сумм или хешами различных частей кода, таких как идентификатор,
Info.plist
, основная исполнимая программа, файлы ресурсов, и т.д. Изоляция может использоваться для обнаружения изменений к коду и к идентификатору приложения.Цифровая подпись, подписывающая изоляцию для гарантии ее целостности. Подпись включает информацию, которая может использоваться для определения, кто подписал код и допустима ли подпись.
Уникальный идентификатор, который может использоваться, чтобы идентифицировать код или определить, которым группам или категориям принадлежит код. Этот идентификатор может быть получен из содержания
Info.plist
для приложения, или может быть предоставлен явно подписывающим лицом.
Для большего количества обсуждения цифровых подписей посмотрите следующий раздел, Цифровые подписи и Код Со знаком.
Чтобы узнать больше, как подпись кода используется для определения степени доверия кода со знаком в определенной цели, посмотрите Требования Кода.
Обратите внимание на то, что подписывание кода имеет дело прежде всего с рабочим кодом. Несмотря на то, что это может использоваться для обеспечения целостности сохраненного кода (на диске, например), это - вторичное использование.
Для осознавания использования подписывания кода необходимо знать о некоторых вещах, которые не может сделать подписание:
Это не может гарантировать, что часть кода свободна от уязвимостей системы обеспечения безопасности.
Это не может гарантировать, что приложение не загрузит небезопасный или измененный код — такой как недоверяемые плагины — во время выполнения.
Это не технология управления цифровыми правами (DRM) или защиты от копирования. Несмотря на то, что система могла решить, что копия Вашего приложения не была должным образом подписана Вами, или что его защита от копирования была взломана, таким образом делая подпись недопустимой, нет ничего, чтобы препятствовать тому, чтобы пользователь выполнил приложение так или иначе.
Цифровые подписи и код со знаком
Как объяснено в Обзоре безопасности, цифровая подпись использует шифрование с открытым ключом для обеспечения целостности данных. Как подпись, записанная с чернилами на бумаге, цифровая подпись может использоваться, чтобы идентифицировать и аутентифицировать подписывающее лицо. Однако цифровую подпись более трудно подделать и идет один шаг вперед: это может гарантировать, что не были изменены данные со знаком. Это несколько походит на разработку бумажной проверки или денежного перевода таким способом, которым, если кто-то изменяет записанную сумму денег, водяной знак с «Недопустимым» текстом становится видимым на бумаге.
Для создания цифровой подписи программное обеспечение подписания вычисляет специальный тип контрольной суммы, вызвал хеш (или обзор) на основе части данных или кода и шифрует тот хеш с закрытым ключом подписывающего лица. Этот зашифрованный хеш вызывают подписью.
Для заверения той подписи программное обеспечение проверки вычисляет хеш данных или кода. Это тогда использует открытый ключ подписывающего лица для дешифрования подписи, таким образом получая исходный хеш, как вычислено подписывающим лицом. Если два хеша соответствуют, данные не были изменены, так как они были подписаны кем-то во владении закрытым ключом подписывающего лица.
Код со знаком содержит несколько цифровых подписей:
Если код универсален, объектный код для каждой части (архитектура) подписывается отдельно. Эта подпись сохранена в самом двоичном файле.
Различные компоненты комплекта приложений (такой как
Info.plist
файл, если существует один), также подписываются. Эти подписи сохранены в вызванном файле_CodeSignature/CodeResources
в пакете.
Требования кода
Именно до системы или программы запускает или загружает подписанный код, чтобы решить, заверить ли подпись и, если это делает, чтобы определить, как оценить результаты той проверки. Критерии, используемые для оценки подписи кода, вызывают требованиями кода. Подписывающее лицо может указать требования при подписании кода; такие требования упоминаются как внутренние требования. Верификатор может считать любые внутренние требования прежде, чем решить, как обработать код со знаком. Однако это до верификатора для решения что требования использовать. Например, Safari мог потребовать, чтобы плагин был подписан Apple, чтобы быть загруженным, независимо от того, включала ли подпись того плагина внутренние требования.
Одна главная цель подписей кода состоит в том, чтобы позволить верификатору идентифицировать код (такой как программа, плагин или сценарий), чтобы определить, является ли это тем же кодом, который верификатор видел прежде. Критерии, используемые для создания этого определения, упоминаются как определяемое требование кода. Например, определяемое требование для Почты Apple могло бы быть, «был подписан Apple, и идентификатор com.apple.Mail
".
Чтобы видеть, как это работает на практике, предположите, что пользователь дал разрешение к Почтовому приложению Apple получать доступ к элементу цепочки для ключей. Цепочка для ключей использует определяемое требование Почты для идентификации его: цепочка для ключей записывает идентификатор (com.apple.Mail
) и подписывающее лицо приложения (Apple) для идентификации программы позволило получать доступ к элементу цепочки для ключей. Каждый раз, когда Почта пытается получить доступ к этому элементу цепочки для ключей, цепочка для ключей смотрит на подпись Почты, чтобы удостовериться, что программа не была повреждена, что идентификатор com.apple.Mail
, и что программа была подписана Apple. Если все проверяет, цепочка для ключей предоставляет Почтовый доступ к элементу цепочки для ключей. Когда Apple выпускает новую версию Почты, новая версия включает подпись, поставленную Apple, идентифицирующим приложение как com.apple.Mail
. Поэтому, когда пользователь устанавливает новую версию Почты, и это пытается получить доступ к элементу цепочки для ключей, цепочка для ключей распознает обновленную версию как ту же программу и не предлагает пользователю проверку.
Архитектурно, требование кода является сценарием, записанным на специализированном языке, описывающем условия (ограничения), код должен удовлетворить, чтобы быть приемлемым в некоторой цели. Вам решать, ли указать внутренние требования при подписании кода.
Идентификатор программы или все определяемое требование могут быть указаны подписывающим лицом или могут быть выведены codesign
инструмент во время подписания. В отсутствие явно указанного определяемого требования, codesign
утилита обычно создает определяемое требование из имени программы, найденной в Info.plist
файл и цепочка подписей, защищающих подпись кода.
Обратите внимание на то, что проверка кода со знаком против ряда требований выполняется только, когда система или некоторая другая программа должны определить, безопасно ли доверять тому коду. Например, код без знака, введенный в приложение посредством переполнения буфера, может все еще выполниться, потому что это не была часть приложения во время запуска. Точно так же приложение с недопустимым идентификатором кода может все еще работать (в зависимости от политики), но не получает автоматический доступ к элементам цепочки для ключей, создаваемым предыдущими версиями приложения.
Роль доверия подписыванию кода
Доверие определяется политикой. Политика доверия безопасности определяет, должны ли определенные идентификационные данные быть приняты для разрешения чего-то, такого как доступ к ресурсу или службе. Различные части OS X имеют различные политики и делают это определение по-другому. Например, специализированное клиентское приложение могло бы включать ряд корневых сертификатов, которым это доверяет при передаче с определенным набором серверов. Если бы к тем тем же серверам получили доступ с помощью веб-браузера, Однако этим корневым сертификатам не доверяли бы.
Почти таким же способом много частей OS X (цепочка для ключей OS X и родительский контроль, например) не заботятся о том, какой объект подписал приложение; они заботятся только, изменилось ли подписывающее лицо с прошлого раза была проверена подпись. Они используют определяемое требование подписи кода с этой целью.
Другие части OS X ограничивают приемлемые подписи к только нарисованным из центров сертификации (корневые сертификаты), которые являются доверяемыми привязками в системе, выполняющей проверку. Для тех проверок природа идентификационных данных использовала вопросы. Брандмауэр Приложения является одним примером этого типа политики. Самоподписанные идентификационные данные и самосоздаваемые центры сертификации не работают в этих целях, если пользователь явно не сказал операционной системе доверять сертификатам.
Можно изменить полицейских подписывания кода OS X с spctl(8)
команда.