Недавно я участвовал в Ethereum-хакатоне, и сегодня хочу рассказать о проекте EtherAuth, с которым команда MixBytes заняла третье место. EtherAuth — это попытка сделать децентрализованную версию входа на сайт при помощи внешней учетной записи. Как кнопка войти через Facebook, только без Facebook.


Проблема и пути решения


Если вы хотите сделать на своем сайте закрытую область для пользователей, вам приходится выбирать: разработать свою систему идентификации, аутентификации и авторизации пользователей, или воспользоваться готовым решением. Готовое решение означает, что у вашего пользователя уже есть учетная запись в какой-то системе (Facebook, Google, Yahoo, Outlook, или даже просто email). И вы используете соответствующий механизм (чаще всего протокол OAuth 2.0), чтобы убедиться, что некто пытающийся залогиниться на ваш сайт с использованием внешнего идентификатора пользователя и есть этот пользователь.


Последний вариант проще в реализации, но возникает риск для пользователя: если что-то случится с его основным аккаунтом (например, Facebook заблокирует аккаунт без объяснения причин), он потеряет также доступ и к своей информации на вашем сайте.
Кроме того, если я как пользователь хочу войти на какой-то сайт, которому я пока не доверяю, я сталкиваюсь с необходимостью предоставить этому сайту доступ к своей персональной информации, например email или возраст. Если сайт поддерживает только вход внешней учетной записью, я должен буквально сделать выбор: отказаться от использования сайта или пожертвовать своей анонимностью.


Большинство пользователей заканчивает тем, что жертвует анонимностью со словами «да что страшного может случиться, мне нечего скрывать». К несчастью, большинство атак, ориентированных на неподготовленного пользователя и заканчивающихся денежными потерями, начинаются с похожих слов. «Что страшного может случиться, если я перешлю сотруднику банка код из смс?». «Что страшного может случиться если я перешлю сотруднику техподдержки заголовки запроса?». Ответ на этот вопрос чаще всего узнают когда уже ничего нельзя сделать.


Как тут может помочь Ethereum? Мы уже поняли, что основных проблем три:


  1. Пользователь не обязан доверять сайту, на который заходит, и хочет избежать утечки персональной информации.
  2. Сайт хочет использовать внешнюю систему аутентификации, чтобы избежать хранения пользовательских данных и связанных с этим затрат на обеспечение безопасности.
  3. Существующие внешние системы, предоставляющие сайтам возможность аутентификации пользователей, несут в себе опасность цензуры. Любой аккаунт может быть заблокирован в любой момент без объяснения причин и иногда без возможности восстановления.

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


В простейшем случае можно использовать адрес Ethereum-кошелька как идентификатор пользователя. Но здесь возникает проблема: в случае утечки ключа пользователь теряет доступ к системе навсегда. Точнее, с момента, когда секретный ключ пользователя стал известен злоумышленнику или просто случайно попал в публичный доступ, мы не можем использовать такой ключ для аутентификации.


Реализация


В нашем решении я написал простой смарт-контракт EtherAuth для хранения идентификаторов пользователей и связанных с ними адресов кошельков. Идентификатор пользователя — это просто строка UTF-8 размером от 2 до 32 байт. Ее придумывает один раз сам пользователь и позже использует для входа на любой сайт, поддерживающий EtherAuth. Сегодня я бы добавил еще ограничение на возможные символы, входящие в строку, оставив возможность использования символов латинского алфавита и арабских цифр (подмножества 7-битной кодировки ASCII), чтобы ограничить возможность создания внешне похожих логинов.


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


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


Для взаимодействия пользователя со смарт-контрактом мы создали отдельную веб-страницу. На ней можно создать аккаунт, поменять его ключи или удалить. Для работы пользователю потребуется установить браузерный плагин MetaMask. Если вы уже активно используете сеть Ethereum, скорее всего вы этот плагин уже установили, то есть основная масса пользователей, желающих войти на сайт через Ethereum, не столкнется с дополнительной преградой на своем пути.


Общий процесс аутентификации пользователя с использованием EtherAuth выглядит так:


  • Сайт (backend) обращается в смарт-контракт и получает Ethereum-адрес пользователя;
  • Сайт (backend) генерирует и запоминает какое-то сообщение и просит пользователя подписать это сообщение при помощи адреса authKey;
  • Пользователь, находясь на сайте (frontend), подписывает сообщение при помощи плагина MetaMask и отправляет его в backend;
  • Сайт (backend) проверяет подпись, и если все в порядке, активирует сессию пользователя в соответствии со своей выбранной логикой.

В нашем решении для хакатона мы для простоты совместили backend- и frontend-части, получился один большой frontend. В реальной жизни важно, чтобы проверка аутентификации происходила в неподконтрольной пользователю среде, то есть не в браузере, а на сервере.


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


В результате за два дня мы получили proof-of-concept децентрализованной аутентификации с использованием сети Ethereum и плагина MetaMask. Мы понимаем, как нужно доработать эту систему, чтобы добавить в нее анонимность для пользователя. Пользователь имеет возможность восстановить доступ в случае утечки его основного ключа (но не в случае утечки ключа восстановления). Децентрализованная система неподвластна цензуре крупных структур, таких как Google или Facebook. При необходимости цензуры сайт должен осуществлять ее самостоятельно, но он может сделать это только в рамках собственной системы, не влияя на доступ пользователя к другим системам. Сеть Ethereum не очень быстро проводит транзакции (при создании аккаунта пользователю может быть придется подождать несколько минут), но доставать данные и осуществлять проверку аутентификации пользователя можно очень быстро. Это решение хорошо масштабируется, поскольку узлов с данными очень много, и любой желающий может добавить еще один в любой момент. Трудоемкость же внедрения такого решения для владельцев сайтов не выше, чем трудоемкость внедрения поддержки OAuth 2.0.


Заключение


Безусловно, сегодня пользователей использующих сеть Ethereum ничтожно мало в сравнении с числом пользователей Facebook. Однако популярность блокчейн-технологий растет, и я верю, что в обозримом будущем таких пользователей будет становиться все больше и больше, а значит появится возможность для использования децентрализованной аутентификации в промышленных системах.


Ссылки


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


  1. rt3879439
    12.09.2018 13:28
    -1

    Мартышка и очки. Осталась хоть одна область в которой не попытались использовать блокчейн?


    1. BoogerWooger
      12.09.2018 23:13

      ах Моська, знать она сильна…


      1. roscomtheend
        13.09.2018 10:04

        А вы, друзья, как ни садитесь, с блокчейном вы не пригодитесь.


        1. BoogerWooger
          13.09.2018 12:32

          Про мартышку было всё таки ближе к истине — очень много тех кто крутит блокчейн и та и сяк, стараясь присобачить хоть как то к своему бизнесу, чтобы срубить бабла.
          А вот на identity зря ругаетесь — здесь как раз блокчейн очень даже применим — крайне удобно самому управлять своими идентификационными данными и аккаунтами, не завися ни от каких внешних сервисов.


  1. TimsTims
    12.09.2018 14:45

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

    Пользователь имеет возможность восстановить доступ в случае утечки его основного ключа (но не в случае утечки ключа восстановления).
    Ну вот и получается, что если ты потерял код/забыл пароль, то всё — аккаунт ты уже никак не восстановишь. Если информация на сайте не ценная, то хрен бы с ним. А если у тебя там куча всяких подписок, то начинаются танцы с бубном — докажи, что владеешь. И уже админ будешь решать — перекидывать ли доступ, или нет, и вот снова включается человеческий фактор, блокчейн не нужен.


    1. mxpaul Автор
      12.09.2018 15:36

      OAuth от гугл, фейсбука итд еще хорош и тем, что усложняет массовую регистрацию ботов, т.к. нужно попотеть еще с регистрацией там.
      Если хотите заставить пользователя попотеть, всегда можно воспользоваться технологией типа этой github.com/poanetwork/poa-popa. Пользователь получает открытку по почте, вводит код с нее, профит. Бот не пройдет.

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

      Ну вот и получается, что если ты потерял код/забыл пароль, то всё — аккаунт ты уже никак не восстановишь.
      Потерять бумажку из сейфа примерно так же сложно как потерять номер телефона. А попробуйте гугл аккаунт восстановить без доступа к телефону, даже если помните пароль, но Google хочет убедиться что вы это вы. Это не придуманный кейс, это реальная проблема из моего опыта. Нерешенная.


  1. vlasenkofedor
    12.09.2018 23:08

    Сколько пользователю нужно потратить времени и свободного места, чтобы создать в этой системе аккаунт? Какими знаниями должен обладать пользователь, чтобы зарегистрироваться?


    1. BoogerWooger
      12.09.2018 23:20

      Нужно просто уметь отправить транзакцию в Ethereum. Если использовать тестовую сеть то от начала установки метамаска до первого логина — где то минута, да и то — это чтобы записать seed фразу. Если нужна боевая сеть, то потребуется сам эфир, где то на одну транзакцию (это от нескольких центов до доллара, в зависисмости от нагрузки на сеть)


  1. ValdikSS
    12.09.2018 23:23

    Система аутентификации на сайтах EmerSSL от Emercoin работает с 2015 года, но, увы, особой популярности не сыскала.
    Считаю, что сервисы Emercoin круты, и, вероятно, обгоняют своё время.


    1. BoogerWooger
      13.09.2018 12:39

      EmerSSL — классная, давно про нее знаю, она куда изящней и технологичней централизованной системы сертификатов. Мы тоже думаем, что для децентрализованной identity еще рано, равно как и для широкого использования смарт-контрактов. Люди только освоили восстановление аккаунтов по емейлу и не желают тыкать ни во что, сложнее чем лайк или «login with Facebook». Но как прижмет, уверен, научатся быстро.


  1. vlasenkofedor
    12.09.2018 23:49

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

    Здесь время расставит все на свои места.


  1. vba
    13.09.2018 11:47

    То что не говорят на хакатоне Ethereum:
    Главная проблема в Ethereum это throughput и именно количество транзакций в секунду. Эта величина если мне не изменяет память, ничтожна мала. Так что какой смысл такой системы в продакшене. Можно конечно смотреть в сторону Hyperledger, но это тоже не вариант на мой взгляд, для такого рода задач.


    1. mxpaul Автор
      13.09.2018 12:30

      Ну нет, проблема пропускной способности в данном случае сильно преувеличена. Про это написано в статье.

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


    1. BoogerWooger
      13.09.2018 12:58

      Как раз для identity скорость сети эфира вполне себе нормальная — перевыпуск ключа — ситуация крайне редкая и эфир без проблем потянет. Если каждый пользователь перевыпускает ключ раз в полгода, то никаких нагрузок на сеть не будет. А проверяется авторизация off-chain и тут можно как угодно разгонять сервис, хоть до миллиона запросов в секунду — это ж просто проверка подписи, она не требует ходить в эфир.
      Hyperledger для персональных identity — точно не вариант. Ценность identity в том, что я сам контролирую свои аккаунты и никто не забанит мой аккаунт и не отключит. Hyperledger — штука централизованная, я бы ей точно не доверил свою identity. Вместо него можно публичную MySQL поставить — толку будет столько же.

      Ну а про «throughput» — чесгря не очень здорово, когда люди обсуждают количество транзакций в секунду, так, как будто это единственное число, которым блокчейны меряются. Никто из системных архитекторов не оперирует одним лишь числом транзакций в секунду — эта метрика годится для какого нибудь примитивного API с приблизительно одинаковым паттерном использования, во всех остальных случаях количество транзакций в секунду имеет смысл обсуждать только под конкретные задачи, с указанием всех условий и точным описанием того, что считать «концом» транзакции, какова цена отката, и еще десятка важных параметров. Оно зависит от типа транзакций (большие или маленькие), характера транзакций (требуют исполнения серьезных кода или нет), устойчивости к разделению сети, от типа финализации блоков (например в биткоине и эфире математически, пропускная способность может быть 0 транзакций за тысячу лет, ибо алгоритм консенсуса — вероятностный). Никто не спорит про скорость обработки транзакций в блокчейне, разумеется она медленней на порядки, чем в централизованных сервисах, но за это вы получаете независимую от кого бы то ни было и неоспоримую обработку ваших данных, и для identity этот фактор гораздо важнее, чем скорость.


      1. vba
        13.09.2018 13:42

        Класс, спасибо. Я не с теми "спецами" по блокчейну до этого видимо общался.
        Как насчет ситуации когда пользователь меняет личные данные, типа фамилии или адреса итд, они тоже случаются не часто, но может ли это быть своего рода вектором атаки на такого рода систему?


        1. BoogerWooger
          13.09.2018 17:12

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


  1. denis_skripnik
    13.09.2018 16:21

    Лучше сделать EOS смартконтракт, а затем запустить с использованием API eos-js. И никаких метамасков не надо…


    1. mxpaul Автор
      13.09.2018 16:29

      Для хакатона по Ethereum было бы большим вызовом сделать проект на EOS :-)

      Если серьезно, аналог metamask для EOS это scatter, и как реализовать без него что-то подобное я не очень представляю. Пользователь должен использовать свой кошелек, eos-js это только прослойка в браузере между кошельком и блокчейном, так же как web3 в Ethereum.

      Сам по себе EOS хорош, но говорить что на нем однозначно делать лучше имхо как-то преждевременно.


      1. denis_skripnik
        13.09.2018 18:50

        Согласен, что ещё рано говорить. Но я уже начинаю изучать эту тему, так как считаю перспективной.


    1. BoogerWooger
      13.09.2018 17:15

      Для эфира точно так же можно использовать web3.js без всякого метамаска. Правда от необходимости иметь эфир для отправки транзакций и ставить подпись на транзакцию это не спасет. Большой разницы на фронтенде между EOS и Etheereum нет.


      1. denis_skripnik
        13.09.2018 18:49

        Про web3.js слышал, но мельком. А может и не слышал. Благодарю — изучу.

        А что касается ETH для отправки транзакции — да. В EOS, кажется, можно не платить пользователю за транзакцию, Так как DApp приобретают ресурсы. Только вот, как было сказано в одном ответе на мой комментарий, о том, чтобы делать что-то для EOS, говорить рано. Хотя я планирую изучать то, как делать смартконтракты для того блокчейна, потому что считаю перспективным направлением.