Если нужно подписать файл, чтобы гарантировать его аутентичность, что мы делаем? Старый способ — запустить PGP и сгенерировать подпись, используя команду --sign. Цифровая подпись удостоверяет создателя и дату создания документа. Если документ будет как-то изменён, то проверка цифровой подписи это покажет. Одновременно нужно опубликовать в открытом доступе свой публичный ключ, чтобы любой желающий мог проверить подпись.

Но использовать PGP — не лучшая идея. Есть варианты получше. Например, теперь подписывать документы/файлы можно с помощью обычной утилиты OpenSSH.

Вообще, ключ SSH — очень удобная штука. Не только для подписи текстов и коммитов в Git, но и для авторизации на сайтах. А также для шифрования сообщений, которые сможет прочитать только один человек.

Проблема PGP


Много лет специалисты по безопасности говорят о недостатках PGP.

«Если не вдаваться в подробности, основная причина в том, что программа разработана в 90-е годы, до появления серьёзной современной криптографии. Ни один компетентный криптоинженер сегодня не станет разрабатывать систему в таком виде и не потерпит большинства её дефектов ни в какой другой системе. Серьёзные криптографы в основном отказались от PGP и больше не тратят на неё времени (за некоторыми заметными исключениями). Поэтому хорошо известные проблемы в PGP остаются нерешёнными более десяти лет». — Проблема PGP

Основные проблемы:

  • Абсурдная сложность. Восемь способов кодирования длины пакета. Пакеты и подпакеты. Некоторые варианты пакетов перекрываются друг с другом. Ключи и подключи. Идентификаторы ключей, серверы ключей, подписи ключей. Ключи только для подписи и только для шифрования. Связки ключей. Аннулирование сертификатов. Три различных формата сжатия
  • Универсальный дизайн: выполняет множество задач, но не заточен ни под какую
  • Болото обратной совместимости
  • Неприятный UX
  • Неудобные цифровые подписи для аутентификации шифротекста
  • Непоследовательные идентити
  • Открытые ключи гигантского размера
  • Мусорный код в OpenPGP

Как видим, неудобные цифровые подписи для аутентификации называют одной из основных проблем PGP.

Но вообще количество проблем такое, что некоторые предпочитают вообще держаться подальше от PGP.

OpenSSH вместо PGP для подписи


С версии OpenSSH 8.0 можно использовать команду ssh-keygen для подписи и верификации подписей на произвольных данных, включая файлы, релизы программного обеспечения, вообще любые данные.

Это реально удобная функция, потому что OpenSSH — очень распространённый стандарт. С современными дистрибутивами Linux (например, Ubuntu 20.04 и новее) программа устанавливается по умолчанию. OpenSSH легко устанавливается на Windows 10/11 и другие операционные системы. Например, под Windows последняя версия openssh-portable v8.6.0.0p1-beta от 27 мая 2021 года, установить в директорию \Program Files\OpenSSH-Win64.

Как вариант, включаем клиент, встроенный в систему через Feature on Demand (FoD) в терминале:

Add-WindowsCapability -Online -Name OpenSSH.Server*

Или при помощи DISM:

dism /Online /Add-Capability /CapabilityName:OpenSSH.Server~~~~0.0.1.0

То же самое через панель «Управление дополнительными компонентами → Добавить компонент → Сервер OpenSSH».



Если у вас уже есть ключи, то можете с их помощью генерировать подписи. Если нет, то устанавливаем программу и генерируем ключи.

ssh-keygen



Сгенерированный секретный ключ хранится в файле id_rsa:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,20F9A7DFF2C11AA4380AC0B07789DB77

LX8lpLB4/islDPqIpc52cOatrNUiUJm8MdpBLu89Zk6wmVySp/vfaKUwxz7mE6kA
V7GjJBgyUJE2x6L8U0FZTO/tJDaf8+yj28JvETJ62usIFbMfX/5+D6NIOsQp1HFu
5qyg+aOzWjYG5wkAyKq756G/fNdHiMrx2dklxMbhHFN1sI///0vcExIuggI0eEMI
Y3RDvMSlr0GY8DWOs2Wp8cmshsIQSXdNQJh6JhCyHTG+0lvVXWYppzTjHt0Og1Sa
rsjF7Rd2bY3Un/rSLPcrSg7q564I8bCA/4HbmDjWM5012jPEqMOcG7pHxxqUucRG
L4B9x1BxjXAFmzWWm/BFA/oYYXuUFv4DItVLmYn6Ilqw5v87bvCuEAiWGJWmmf+D
Bb3V4CCQ+Q7/o5D9YXLgNsKMaUlP7ZVDMhKCN+cm+0j/t2ip3dAEETrpVdEQV3zr
R0Ip7XgrujKiAzTf/x2gSkoVXkFU3qdiwSlfudHxsn7Mtw25jbAhyTfnV4j4/YRq
euOg7rPVS14K/n9Yw3gSEZl1CrS+CVhnJDqE+zfLqkNNcgFxs0NOKjUryfnhBV8X
IJ4aKELBlcWj71Iv+yh3d1vNNwDqh8U1jKakjqZU7JpVDHs2TPOAlqbA0Pe3k9zB
pJMMUxedVZP2kIC2UDAwMdGb9Bo63mAHsGtJckbFvAoCOyFt7pAJ/b4sKKsQrojo
abY3yyY7Xe/aLvdsNHQcLv68cOl8vu1RJUCtUB/g5kI2zpONsi1M9BGZEyzEc3ol
vb6+/ZM7X27k3AqvymDK6vL8vYj5f04BjRGw0BVy2LjhHlSzDy8PEI4E7RA2yL2P
gRmQw2Fqg9jw6EUbxvonFja0z61QTafFcz6TN0zdrpJaQ9PhYivF6EbIqtjAoCaU
fCpOjmcUcnwDYmOvIVZLQOGUH5AIL7H3A7vEHT9cAZ35yfUQq4eflVirdH9y82mo
nPEDsM/XEa4KFyHsjXN/t1Tv1uY3Pft4LQRcyro41ionFIBpOsrqe9UJzYkjB4G0
eMkfM8PGpgGwS1LjTWZUKnD3TmEpcQc55eYbRKnXj3zMuFX9DzCtxGuisvR/2irP
WjpWTq10YQ8D6gnDBqtkj/QULdKd/2/coi8uLLFlzBi91aellpKFOmf9yHKw7TJ+
5anZhT63PpIe9v7vJq6T1q+I8Bi7LTDvEOtJTBU7Dkb7k2kpUY/qM2GSuU4MqQ6D
Ph3+iJs3c1jJrGSuxL3JyQahpJw1VBWocnQWGKtiwm9KqvNVLJ0x+en7qX8Ox+5v
onxH/CbRkN+cjUVW52HSfA2m4ZbTE/1kV0Sb6BToNsqT+sCLHXK/+pZNL+5bOnHa
CelrnBkXJbM1rzPl6Ai6pWqkZ2qMKGUDBRglA3wJ7ddLc/iK5qKBzgrAQAbtcXZH
S6KisfImh/L/qNjh4qf/Cqd9dCZLN7Z9sgCJD+OIy8xE7BA3lqUpMXwR4KrQIR
/8nKf5ks3dglHodThRIK53wCzRhUiAZKZQFKc1TXynTsyfFUFa7bf1m8JiSNZ4Kn
Uv+bTb0OLgV0DjNL67qT1/tiwMjahloAAXRfDx0HqHtZS4t0XPEMX4Rno7G+WZP7
-----END RSA PRIVATE KEY-----

Открытый ключ — в файле id_rsa.pub. В отличие от PGP, здесь ключ представляет собой простой однострочник:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8bOHXwMFwdAjuAsh2GXcQMG3uZTHDFvKpEmTv7ngCSGvM3fYNeP/dCEmHB8Ck1YpfKEErkLhImTeyGIyMEpyB5CXXrwxdj7uLrv1qycZ8sPCRVlwM8XW3bWdmVcOSFec3b0+LfedtUWPPO4wtMOliFHHhptICo/l0t1DV19XW4I0bnSr9Wa96ucmMUho4l2kOXplCU8fJ7izWDQdWsLjA4Xv6BlbA888qzi6IT73thtlfuW3CyvNNEG6smOi2ZAgXVp+ShkRnPpbULGr8D2/91Bwmdca8/zYDPDOnT5eVk3y/QJTgB2IrHW+LAb9F3sydSXJDAPoenOP2BH/UdGB9


Ну и теперь мы можем использовать ключ SSH для подписи любых файлов, команда в Linux:

ssh-keygen -Y sign -f [файл ключа] -n file [файл_для_подписи]

Под Windows для подписи файлов ключом SSH можно использовать signtool.

Сгенерированная подпись записывается в новый файл *.sig в той же директории, который выглядит так:

-----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAg2rirQQddpzEzOZwbtM0LUMmlLG
krl2EkDq4CVn/Hw7sAAAAEZmlsZQAAAAAAAAAGc6hhNTEyAAAAUwAAAAtzc2gtZWQyNTUx
OQAAAEDyjWPjmOdG8HJ8gh1CbM8WDDWoGfm+TTd8Qa8eua9Bt5Cc+43S24i/JqVWmk98qV
YXoQmOYL4bY8t/q7cSNeMH
-----END SSH SIGNATURE-----

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

Самое интересное, что открытые ключи есть у многих пользователей Github, их можно посмотреть по стандартному URL:

https://github.com/USERNAME.keys



Зная открытый ключ человека, можно зашифровать сообщение или файл конкретно для него. Например, с помощью Age:

curl https://github.com/bobuk.keys | age -R - primer.txt > primer.txt.age

Такое сообщение можно свободно публиковать в открытом доступе, например, в этой статье — и только этот конкретный человек сможет его прочитать с помощью своего секретного ключа. В этом вся прелесть PKI.

Другие альтернативы


Существуют и другие варианты подписи документов/файлов вместо PGP, такие как signify и minisign. Но все эти программы надо отдельно устанавливать и генерировать новые ключи. Зачем, если у нас уже есть SSH?

Подпись чужих веб-страниц с помощью TLS


Вообще, с темой аутентификации своих документов пересекается другая технология — цифровая подпись и верификация веб-страниц и любого контента на чужом сайте.

Описание проблемы


Предположим, Алиса хочет доказать Бобу, что на сайте Х гарантированно есть информация Y (или в определённое время она там была). По каким-то причинам Боб не имеет доступа к сайту X и не может самостоятельно проверить информацию Y (например, информацию уже удалили).

Так вот, недавно разработаны методы «нотариального» заверения такой информации своими силами, без использования посторонних сервисов. Всё работает с помощью стандартного протокола TLS, по которому сайт передаёт нам пакеты в зашифрованном виде. Подробно механизм так называемых «децентрализованных оракулов» описан в работе DECO: LiberatingWeb Data Using Decentralized Oracles for TLS (arXiv:1909.00938v4, 18 августа 2020 года).



Научная работа

Если вкратце, DECO работает в три этапа:

  1. рукопожатие трёх сторон
  2. выполнение запроса
  3. генерация доказательства (пруфа)

Таким образом, мы сами выполняем роль нотариуса, гарантированно удостоверяя наличие конкретной информации на данном сайте в указанное время. Получается децентрализованная нотариальная система без «центров доверия» и «сертифицированных нотариусов», как сейчас. В самом деле, зачем это лишнее звено?

Возможные области применения:

  • Конфиденциальные финансовые инструменты, в том числе смарт-контракты (например, исполнение бинарного опциона без передачи секретной информации о его условиях)
  • Проверка возраста человека на сайте без передачи его имени
  • Выявление ценовой дискриминации (разные цены в магазине для разных пользователей)

И так далее… Пока что это новая сфера, тут мало примеров практической реализации. Но зато простор для инноваций.

Комментарии (5)


  1. aegelsky
    22.12.2021 12:03
    +6

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


  1. Tangeman
    22.12.2021 21:16
    +3

    Если нет, то устанавливаем программу и генерируем ключи.

    Зачем же генерировать эти ужасно длинные RSA ключи по умолчанию, если можно сделать короткие ed25519 без потери качества?


    Например, ssh-keygen -t ed25519 производит довольно короткую строку для паблик-ключа (её удобно копировать):
    ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH5KCvDh/K5lRJW1f4X+wpt0PIrLwvbtSf3YIqqh1/tY user@localhost


  1. cranium256
    22.12.2021 21:23
    +1

    Не раскрыта тема подписи чужих веб-страниц с помощью TLS. Научная работа — это здорово, но где простое общепонятное руководство по «нотариальному» заверению такой информации своими силами?


    1. andreykp
      23.12.2021 23:02

      еще очень не хватает технической части, как проверять, что именно гарантируется, как посмотерть отметку времени, как удостоверится что она подписана третьей стороной (СЦ), как удостоверится что содержимое подписано сертификатом сервера, как удостоверится что он валиден


  1. artemisia_borealis
    22.12.2021 21:52
    +1

    Не раскрыта также тема подписи e-mail из обычного MTA, к примеру из Thunderbird'а. (Для PGP такие плагины есть и очень давно.)

    Так же стоило бы упомянуть, раз уж мы о безопасности говорим, что последняя версия это 8.8, и упомянутая под win версия 8.6 уже немного поотстала. C BSD/Linux этой проблемы нет, но в win надо иметь в виду. (А перед этим была ещё 8.7, где тоже были изменения и фиксы).

    И всякие powershell'ы это явно оверинженириг. Это же просто архив с бинарниками. Его можно распаковать куда удобно и прописать системный путь до этого каталога.