Сам себе нотариус. Используем OpenSSH для подписи файлов и TLS для нотариального заверения веб-страниц

image-loader.svg

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

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

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


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

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


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

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


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

Но вообще количество проблем такое, что некоторые предпочитают вообще держаться подальше от 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».

image-loader.svg

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

ssh-keygen


image-loader.svg

Сгенерированный секретный ключ хранится в файле 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

image-loader.svg

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

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


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

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


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


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

image-loader.svg

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


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

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


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

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

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


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

© Habrahabr.ru