Проверка целостности дистрибутивов: различия между версиями

Материал из SysWiki
показана проверка файла при помощи файла с подписью
изменение оформления
Строка 24: Строка 24:
Откроем в браузере адрес https://www.python.org/ftp/python/, там найдём подкаталог с последней версией, на момент написания данного материала это 3.12.0, перейдём в него и загрузим оттуда файлы Python-3.12.1.tar.xz (исходные тексты Python), Python-3.12.1.tar.xz.asc (файл подписи). Или можно скачать из командной строки эти файлы командой:
Откроем в браузере адрес https://www.python.org/ftp/python/, там найдём подкаталог с последней версией, на момент написания данного материала это 3.12.0, перейдём в него и загрузим оттуда файлы Python-3.12.1.tar.xz (исходные тексты Python), Python-3.12.1.tar.xz.asc (файл подписи). Или можно скачать из командной строки эти файлы командой:


wget '<nowiki>https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tar.xz'</nowiki> '<nowiki>https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tar.xz.asc'</nowiki>
  wget <nowiki>https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tar.xz</nowiki> <nowiki>https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tar.xz.asc</nowiki>


Теперь мы можем попробовать проверить подлинность файла командой:
Теперь мы можем попробовать проверить подлинность файла командой:


<code>gpg --verify Python-3.12.1.tar.xz.asc</code>
  gpg --verify Python-3.12.1.tar.xz.asc


Результат получился такой:
Результат получился такой:


gpg: предполагается, что подписанные данные находятся в 'Python-3.12.1.tar.xz'
  gpg: предполагается, что подписанные данные находятся в 'Python-3.12.1.tar.xz'
 
  gpg: Подпись сделана Пт 08 дек 2023 00:02:02 MSK
gpg: Подпись сделана Пт 08 дек 2023 00:02:02 MSK
  gpg:                ключом RSA с идентификатором 7169605F62C751356D054A26A821E680E5FA6305
 
  gpg: Не могу проверить подпись: No public key
gpg:                ключом RSA с идентификатором 7169605F62C751356D054A26A821E680E5FA6305
 
gpg: Не могу проверить подпись: No public key


Как видно, проверить подпись не удаётся из-за отсутствия нужного открытого ключа (его идентификатор 7169605F62C751356D054A26A821E680E5FA6305 указан в сообщении об ошибке, которое вывела программа gpg). Ключи для проверки дистрибутивов Python можно скачать на странице https://www.python.org/downloads/ — на странице есть раздел «OpenPGP Public Keys», где мы видим нужный ключ (указан идентификатор ключа, точнее, его последняя часть, которая соответствует идентификатору того ключа, который мы ищем. Скачаем его (его можно загрузить по ссылке https://github.com/Yhg1s.gpg). Откроем в консоли каталог, где был сохранён ключ, и импортируем его базу ключей GnuPG:
Как видно, проверить подпись не удаётся из-за отсутствия нужного открытого ключа (его идентификатор 7169605F62C751356D054A26A821E680E5FA6305 указан в сообщении об ошибке, которое вывела программа gpg). Ключи для проверки дистрибутивов Python можно скачать на странице https://www.python.org/downloads/ — на странице есть раздел «OpenPGP Public Keys», где мы видим нужный ключ (указан идентификатор ключа, точнее, его последняя часть, которая соответствует идентификатору того ключа, который мы ищем. Скачаем его (его можно загрузить по ссылке https://github.com/Yhg1s.gpg). Откроем в консоли каталог, где был сохранён ключ, и импортируем его базу ключей GnuPG:


gpg --import Yhg1s.gpg
  gpg --import Yhg1s.gpg


Если мы повторно выполним команду <code>gpg --verify Python-3.12.1.tar.xz.asc</code>, то получим уже новый результат, показывающий, что подпись верна, но уверенности в подлинности ещё нет, поскольку у системы нет данных, позволяющих убедиться, что открытый ключ принадлежит владельцу:
Если мы повторно выполним команду <code>gpg --verify Python-3.12.1.tar.xz.asc</code>, то получим уже новый результат, показывающий, что подпись верна, но уверенности в подлинности ещё нет, поскольку у системы нет данных, позволяющих убедиться, что открытый ключ принадлежит владельцу:


gpg: предполагается, что подписанные данные находятся в 'Python-3.12.1.tar.xz'
  gpg: предполагается, что подписанные данные находятся в 'Python-3.12.1.tar.xz'
 
  gpg: Подпись сделана Пт 08 дек 2023 00:02:02 MSK
gpg: Подпись сделана Пт 08 дек 2023 00:02:02 MSK
  gpg:                ключом RSA с идентификатором 7169605F62C751356D054A26A821E680E5FA6305
 
  gpg: Действительная подпись пользователя "Thomas Wouters <thomas@python.org>" [неизвестно]
gpg:                ключом RSA с идентификатором 7169605F62C751356D054A26A821E680E5FA6305
  gpg:                 или "Thomas Wouters <thomas@xs4all.nl>" [неизвестно]
 
  gpg:                 или "Thomas Wouters <twouters@google.com>" [неизвестно]
gpg: Действительная подпись пользователя "Thomas Wouters <thomas@python.org>" [неизвестно]
  gpg: Внимание: Данный ключ не заверен доверенной подписью!
 
  gpg:           Нет указаний на то, что подпись принадлежит владельцу.
gpg:                 или "Thomas Wouters <thomas@xs4all.nl>" [неизвестно]
 
gpg:                 или "Thomas Wouters <twouters@google.com>" [неизвестно]
 
gpg: Внимание: Данный ключ не заверен доверенной подписью!
 
gpg:           Нет указаний на то, что подпись принадлежит владельцу.


Отпечаток первичного ключа: 7169 605F 62C7 5135 6D05  4A26 A821 E680 E5FA 6305
Отпечаток первичного ключа: 7169 605F 62C7 5135 6D05  4A26 A821 E680 E5FA 6305
Строка 66: Строка 56:
Мы скачали ключ по ссылке с официального сайта, но давайте проявим дополнительную бдительность и посмотрим, каким был файл в прошлом, на web.archive.org: http://web.archive.org/web/20230101004252/https://www.python.org/downloads/ — там мы увидим соответствующую ссылку для скачивания, и, если откроем сохранённую версию ключа, то можем убедиться, что она идентична той, что мы уже скачали, наверное можно уже считать, что мы проявили достаточную осмотрительность и убедились, что ключ подлинный. Поэтому мы можем подписать этот ключ, чтобы в дальнейшем проверка подписи при помощи GnuPG не вызывала ошибок. Для этого в командной строке введём команду:
Мы скачали ключ по ссылке с официального сайта, но давайте проявим дополнительную бдительность и посмотрим, каким был файл в прошлом, на web.archive.org: http://web.archive.org/web/20230101004252/https://www.python.org/downloads/ — там мы увидим соответствующую ссылку для скачивания, и, если откроем сохранённую версию ключа, то можем убедиться, что она идентична той, что мы уже скачали, наверное можно уже считать, что мы проявили достаточную осмотрительность и убедились, что ключ подлинный. Поэтому мы можем подписать этот ключ, чтобы в дальнейшем проверка подписи при помощи GnuPG не вызывала ошибок. Для этого в командной строке введём команду:


gpg --edit-key 7169605F62C751356D054A26A821E680E5FA6305
  gpg --edit-key 7169605F62C751356D054A26A821E680E5FA6305


Увидим приглашение для ввода команд вида gpg> и введём там команду lsign (завершив ввод переводом строки). Эта команда означает, что вы подписываете ключ только для себя, подпись не будет экспортироваться (есть также варианты sign, tsign и т.д., о которых вы можете прочитать в документации), при её выполнении нужно будет дважды подтвердить осуществляемые действия введя «y», после чего можно завершить работу в GnuPG с сохранением командой <code>save</code>.
Увидим приглашение для ввода команд вида gpg> и введём там команду lsign (завершив ввод переводом строки). Эта команда означает, что вы подписываете ключ только для себя, подпись не будет экспортироваться (есть также варианты sign, tsign и т.д., о которых вы можете прочитать в документации), при её выполнении нужно будет дважды подтвердить осуществляемые действия введя «y», после чего можно завершить работу в GnuPG с сохранением командой <code>save</code>.
Строка 72: Строка 62:
Теперь команда gpg --verify Python-3.12.1.tar.xz.asc покажет нам результат проверки подлинности дистрибутива Python:
Теперь команда gpg --verify Python-3.12.1.tar.xz.asc покажет нам результат проверки подлинности дистрибутива Python:


gpg: предполагается, что подписанные данные находятся в 'Python-3.12.1.tar.xz'
  gpg: предполагается, что подписанные данные находятся в 'Python-3.12.1.tar.xz'
 
  gpg: Подпись сделана Пт 08 дек 2023 00:02:02 MSK
gpg: Подпись сделана Пт 08 дек 2023 00:02:02 MSK
  gpg:                ключом RSA с идентификатором 7169605F62C751356D054A26A821E680E5FA6305
 
  gpg: проверка таблицы доверия
gpg:                ключом RSA с идентификатором 7169605F62C751356D054A26A821E680E5FA6305
  gpg: marginals needed: 3  completes needed: 1  trust model: pgp
 
  gpg: глубина: 0  достоверных:   5  подписанных:   5  доверие: 0-, 0q, 0n, 0m, 0f, 5u
gpg: проверка таблицы доверия
  gpg: глубина: 1  достоверных:   5  подписанных:   1  доверие: 5-, 0q, 0n, 0m, 0f, 0u
 
  gpg: срок следующей проверки таблицы доверия 2024-12-28
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
  gpg: Действительная подпись пользователя "Thomas Wouters <thomas@python.org>" [полное]
 
  gpg:                 или "Thomas Wouters <thomas@xs4all.nl>" [полное]
gpg: глубина: 0  достоверных:   5  подписанных:   5  доверие: 0-, 0q, 0n, 0m, 0f, 5u
  gpg:                 или "Thomas Wouters <twouters@google.com>" [полное]
 
gpg: глубина: 1  достоверных:   5  подписанных:   1  доверие: 5-, 0q, 0n, 0m, 0f, 0u
 
gpg: срок следующей проверки таблицы доверия 2024-12-28
 
gpg: Действительная подпись пользователя "Thomas Wouters <thomas@python.org>" [полное]
 
gpg:                 или "Thomas Wouters <thomas@xs4all.nl>" [полное]
 
gpg:                 или "Thomas Wouters <twouters@google.com>" [полное]


Итак, GnuPG сообщила нам: «Действительная подпись пользователя "Thomas Wouters <thomas@python.org>" [полное]» — как мы видим, архив подписан одним из участников проекта Python.
Итак, GnuPG сообщила нам: «Действительная подпись пользователя "Thomas Wouters <thomas@python.org>" [полное]» — как мы видим, архив подписан одним из участников проекта Python.

Версия от 19:48, 3 февраля 2024

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

Необходимость проверки

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

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

Использование электронной подписи

Способы проверки подлинности в целом сводятся к использованию электронной подписи, создаваемой при помощи криптографических алгоритмов с открытым ключом, и различаются в деталях реализации, которые подходят для той или иной ситуации. Для Linux основной способ проверки электронной подписи — это использование утилиты GnuPG.

Обычно данная утилита установлена по умолчанию. В случае, если она, например, не установлена в дистрибутиве Debian (что является скорее нештатной ситуацией), её легко установить командой:

apt install gnupg

При этом, для проверки электронной подписи необходимо обладать соответствующим открытым ключом, которые обычно распространяются вместе с подписываемыми файлами и файлами электронной подписи, но есть важный момент с проверкой подлинности открытого ключа: если скачать его с того же сайта, где находится подпись, то, в случае подмены файла, будет скорее всего подменена подпись и открытый ключ. Поэтому, если вы хотите проверить подлинность загружаемого программного обеспечения, можно предпринять дополнительные меры предосторожности, например, скачать открытый ключ заранее (если случаются инциденты с подменой файлов, то они относительно быстро обнаруживаются). Также дистрибутивы Linux могут содержать ряд нужных для проверки ключей. Например, в Debian Linux вы можете установить несколько пактов с ключами используя команду (скорее всего один из них уже будет установлен):

apt install debian-keyring debian-archive-keyring debian-ports-archive-keyring fasttrack-archive-keyring

После этого в каталоге /usr/share/keyrings/ появятся новые файлы с открытыми ключами, связанными с рядом проектов.

Проверка подлинности при помощи электронной подписи для файла

Для файла, подлинность которого нужно подтвердить, создаётся файл электронной подписи, который размещается рядом с ним. Обычно файл подписи имеет расширения .asc, .sig или .sign. Чтобы её проверить, нужно скачать ещё файл ключа, проверить его подлинность, импортировать его и установить степень доверия к нему. Чтобы было понятнее, рассмотрим это на практическом примере, скачаем и проверим целостность исходных текстов Python. Чтобы выполнить все проверки, вам потребуется своя пара ключей, о том, как её сгенерировать, написано в статье про GnuPG.

Откроем в браузере адрес https://www.python.org/ftp/python/, там найдём подкаталог с последней версией, на момент написания данного материала это 3.12.0, перейдём в него и загрузим оттуда файлы Python-3.12.1.tar.xz (исходные тексты Python), Python-3.12.1.tar.xz.asc (файл подписи). Или можно скачать из командной строки эти файлы командой:

 wget https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tar.xz https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tar.xz.asc

Теперь мы можем попробовать проверить подлинность файла командой:

 gpg --verify Python-3.12.1.tar.xz.asc

Результат получился такой:

 gpg: предполагается, что подписанные данные находятся в 'Python-3.12.1.tar.xz'
 gpg: Подпись сделана Пт 08 дек 2023 00:02:02 MSK
 gpg:                ключом RSA с идентификатором 7169605F62C751356D054A26A821E680E5FA6305
 gpg: Не могу проверить подпись: No public key

Как видно, проверить подпись не удаётся из-за отсутствия нужного открытого ключа (его идентификатор 7169605F62C751356D054A26A821E680E5FA6305 указан в сообщении об ошибке, которое вывела программа gpg). Ключи для проверки дистрибутивов Python можно скачать на странице https://www.python.org/downloads/ — на странице есть раздел «OpenPGP Public Keys», где мы видим нужный ключ (указан идентификатор ключа, точнее, его последняя часть, которая соответствует идентификатору того ключа, который мы ищем. Скачаем его (его можно загрузить по ссылке https://github.com/Yhg1s.gpg). Откроем в консоли каталог, где был сохранён ключ, и импортируем его базу ключей GnuPG:

 gpg --import Yhg1s.gpg

Если мы повторно выполним команду gpg --verify Python-3.12.1.tar.xz.asc, то получим уже новый результат, показывающий, что подпись верна, но уверенности в подлинности ещё нет, поскольку у системы нет данных, позволяющих убедиться, что открытый ключ принадлежит владельцу:

 gpg: предполагается, что подписанные данные находятся в 'Python-3.12.1.tar.xz'
 gpg: Подпись сделана Пт 08 дек 2023 00:02:02 MSK
 gpg:                ключом RSA с идентификатором 7169605F62C751356D054A26A821E680E5FA6305
 gpg: Действительная подпись пользователя "Thomas Wouters <thomas@python.org>" [неизвестно]
 gpg:                 или "Thomas Wouters <thomas@xs4all.nl>" [неизвестно]
 gpg:                 или "Thomas Wouters <twouters@google.com>" [неизвестно]
 gpg: Внимание: Данный ключ не заверен доверенной подписью!
 gpg:           Нет указаний на то, что подпись принадлежит владельцу.

Отпечаток первичного ключа: 7169 605F 62C7 5135 6D05  4A26 A821 E680 E5FA 6305

Мы скачали ключ по ссылке с официального сайта, но давайте проявим дополнительную бдительность и посмотрим, каким был файл в прошлом, на web.archive.org: http://web.archive.org/web/20230101004252/https://www.python.org/downloads/ — там мы увидим соответствующую ссылку для скачивания, и, если откроем сохранённую версию ключа, то можем убедиться, что она идентична той, что мы уже скачали, наверное можно уже считать, что мы проявили достаточную осмотрительность и убедились, что ключ подлинный. Поэтому мы можем подписать этот ключ, чтобы в дальнейшем проверка подписи при помощи GnuPG не вызывала ошибок. Для этого в командной строке введём команду:

 gpg --edit-key 7169605F62C751356D054A26A821E680E5FA6305

Увидим приглашение для ввода команд вида gpg> и введём там команду lsign (завершив ввод переводом строки). Эта команда означает, что вы подписываете ключ только для себя, подпись не будет экспортироваться (есть также варианты sign, tsign и т.д., о которых вы можете прочитать в документации), при её выполнении нужно будет дважды подтвердить осуществляемые действия введя «y», после чего можно завершить работу в GnuPG с сохранением командой save.

Теперь команда gpg --verify Python-3.12.1.tar.xz.asc покажет нам результат проверки подлинности дистрибутива Python:

 gpg: предполагается, что подписанные данные находятся в 'Python-3.12.1.tar.xz'
 gpg: Подпись сделана Пт 08 дек 2023 00:02:02 MSK
 gpg:                ключом RSA с идентификатором 7169605F62C751356D054A26A821E680E5FA6305
 gpg: проверка таблицы доверия
 gpg: marginals needed: 3  completes needed: 1  trust model: pgp
 gpg: глубина: 0  достоверных:   5  подписанных:   5  доверие: 0-, 0q, 0n, 0m, 0f, 5u
 gpg: глубина: 1  достоверных:   5  подписанных:   1  доверие: 5-, 0q, 0n, 0m, 0f, 0u
 gpg: срок следующей проверки таблицы доверия 2024-12-28
 gpg: Действительная подпись пользователя "Thomas Wouters <thomas@python.org>" [полное]
 gpg:                 или "Thomas Wouters <thomas@xs4all.nl>" [полное]
 gpg:                 или "Thomas Wouters <twouters@google.com>" [полное]

Итак, GnuPG сообщила нам: «Действительная подпись пользователя "Thomas Wouters <thomas@python.org>" [полное]» — как мы видим, архив подписан одним из участников проекта Python.

Проверка подлинности при помощи подписанных файлов контрольных сумм

Иногда подписывается не файл дистрибутива, а файл, содержащий контрольные суммы загружаемых с сервера файлов. Этот вариант обычно применяется, когда на сервер выкладывается множество вариантов дистрибутива (для разных платформ, для разных языков и т.д.).

Проверка подлинности коммита в репозитории git