Добавлю комментарий про техническую часть. JS библиотека выдает подпись в формате compact, когда как php библиотека основанная на secp256k1 от bitcoin-core почему-то отказывается принимать compact формат (у меня уже не было сил лезть в код php extension на основе си библиотеки). Поэтому php переделывает подпись из compact формата в der перед валидацией.
Авторизация через VIZ на сайте с помощью проверки подписи
В чем существует проблема авторизации на сайте? В большинстве случаев современные сайты требуют регистрации через email или авторизацию через сторонние сервисы: социальные сети, крупные порталы. Но все эти способы все равно основываются на почтовом адресе. Почтовый адрес основывается на домене. Домен принадлежит TLD, которая так или иначе взаимодействует с ICANN.
Исходная точка доверия к домену, его владельца и тем более управления TLD управляется не пользователем. Электронный почтовый адрес временная сущность. У домена сменился владелец? Скорее всего вы лишитесь почты. Владелец домена перестал оплачивать его продление? Вы теряете точку опоры.
Большинство сайтов очень жестко привязаны к регистрируемому у них email адресу. Однажды у меня случилась ситуация, когда я потерял свой адрес из-за смены владельца доменного имени. Попытка перевести аккаунты в разных сервисах на другой email были обречены на провал в 99% случаев. Сменить email в них просто не представляется возможность и они не намерены внедрять такую возможность.
Блокчейн технологии и в частности криптография позволяют видоизменить эти принципы. Зачем доверять авторизацию шаткой структуре? Нестабильной, зависящую от других компаний и людей или их планов? Пользователь сам должен предоставлять доказательство своего существования. Без посредников. И блокчейн этому поможет.
Когда я впервые стал думать над способом авторизации кошелька или аккаунта на сайте, то, естественно, пришел к варианту с секретным ключом. Этапы авторизации в таком случае будут следующие:
- Сайт генерирует ключ (XXXKEY) и хэш сессии (SESSION HASH), передает их пользователю, который хочет авторизоваться на сайте, используя блокчейн.
- Пользователь записывает в блокчейн операцию, содержащую ссылку на свой аккаунт в блокчейне и XXXKEY.
- Сайт анализирует блоки в цепи и когда видит XXXKEY запоминает в сессии, что она принадлежит определенному аккаунту в блокчейне.
- Пользователь теперь обращается к сайту с хэшем сессии в кукисах, что позволяет сайту точно знать, кто перед ним.
Во всей этой истории есть несколько нюансов, который зависят от конкретного блокчейна. На примере VIZ к нюансам относятся: скорость блоков (1 блок в 3 секунды), запись данных в блокчейн (увеличение блока ради простой авторизации), трата пропускной способности аккаунта (с данной проблемой, например, сталкиваются все аккаунты с малым количеством токенов, в том же STEEM). Понятно, что транзакции в DPoS цепочке гораздо подвижнее, чем в POW (в них и за авторизацию придется заплатить комиссию как с обычной транзакции).
Поэтому вопрос быстрой авторизации в веб-сайтах никуда не делся. Это было временное решение, работающее, но его можно было улучшить.
После долгих раздумий был разработан первый план:
- Сайт генерирует ключ (XXXKEY) и хэш сессии (SESSION HASH), передает их пользователю, который хочет авторизоваться на сайте, используя блокчейн.
- Пользователь используя свой приватный ключ (публичный ключ от которого хранится в блокчейне) подписывает им с помощью secp256k1 строку с ключом от сайта XXXKEY, отправляет подпись, наименование аккаунта и ключ сайту.
- Сайт достает публичный ключ в блокчейне от аккаунта, запросившего авторизацию и криптографически сверяет соответствие подписи публичному ключу и XXXKEY, привязывая соответствующую сессию к определенному аккаунту.
Стало хорошо, но можно еще лучше. Второй план заключался в попытке избавиться от запроса ключа. Финальный вариант авторизации включает шаги:
- Пользователь формирует ключ в заданном формате, пример: origin:action:account:autority:unixtime:nonce, подписывает его приватным ключем соответствующего authority и передает сайту подпись и ключ.
- Сайт достает данные из ключа, запрашивает пользователя account из блокчейна. Сверяется, чтобы origin и action были соответствующие его ожиданиям. Сверяет unixtime, чтобы диапазон данного ключа действовал в рамках 2 минут и проверяет подпись на соответствие публичному ключу пользователя. После чего присылает ответ с хэшем сессии.
Данный подход позволяет удостовериться сайту, что перед ним конкретный пользователь, который обладает нужным приватным ключем соответствующий публичному ключу из блокчейна. Такая авторизация заработала на VIZ.World и она гораздо быстрее прошлого способа, не генерирует мусор в блоках и позволяет отказаться от email авторизации вовсе.
Посмотреть код реализации можно на GitHub:
Класс написанный для PHP (работа с ключами блокчейна VIZ, подпись, проверка подписи) — https://github.com/VIZ-World/viz-world-control-panel/blob/master/class/viz_keys.php
Формирование подписи в JS (методы auth_signature_data, auth_signature_check, try_auth_signature) с использованием библиотеки viz-world-js — https://github.com/VIZ-World/viz-world-control-panel/blob/master/js/app.js#L2068-L2151
Проверка подписи на PHP в ajax модуле viz-world-control-panel, действие auth — https://github.com/VIZ-World/viz-world-control-panel/blob/master/module/ajax.php#L4-L81
Перенос центра авторизации от посредников в доверительную среду блокчейна — важный этап для развития Web3. Со временем все больше сайтов будут использовать новую концепцию, но без созидательной силы не получится изменить мир. Думаю, уже сейчас необходимо создавать сайты, которые предложат пользователям альтернативу.
Этап взросления и осознания концепции самодостаточности без посредников уже начался.