бакалавр, Карагандинский технический университет, Казахстан, г. Караганда
РАЗРАБОТКА АЛГОРИТМА WEB АУТЕНТИФИКАЦИИ ПРИ ПОМОЩИ РАСШИРЕНИЯ METAMASK
АННОТАЦИЯ
В статье представлены результаты разработки механизма аутентификации пользователя при помощи MetaMask* расширения для Google Chrome. Приводятся достоинства и недостатки такого подхода. Описан алгоритм и разработано программное обеспечение с использованием Web3.js и Web3j библиотек на языках Java и TypeScript.
ABSTRACT
The article presents the results of developing a user authentication mechanism using the MetaMask* extenxion for Google Chrome. The advantages and disadvantages of this approach are given. An algorithm is described and software is developed using Web3.js and Web3j libraries in Java and TypeScript.
Ключевые слова: аутентификация, web3, MetaMask, Java, TypeScript.
Keywords: authentication, web3, MetaMask, Java, TypeScript.
При реализации авторизации и аутентификации пользователя приходится выбирать между разработкой собственной системы или воспользоваться готовым решением. При разработке собственной системы аутентификации мы обязываем пользователя регистрироваться в нашей системе и берем на себя ответственность за хранение его персональных данных. Последние исследования показывают, что пользователи все чаще прибегают к готовым решениям аутентификации, так как это оказывается более удобным. К готовым решениям можно отнести аутентификацию через Facebook*, Google и т.д. Такой подход предполагает, что пользователь уже имеет учетную запись в одной из приведенных систем.
Данный способ проще в реализации, но он имеет свои недостатки. Первый – если пользователь потеряет доступ к своей учетной записи, он также теряет доступ к своему аккаунту в системе использующей такой способ авторизации. Второй недостаток – пользователю необходимо предоставить доступ к своим персональным данным сторонней системе [4].
Задачи работы заключаются в следующем:
- разработать механизм аутентификации;
- реализовать механизм аутентификации на языках Java и TypeScript;
- проанализировать механизм на потенциальные уязвимости.
Для решения поставленных задач было решено использовать расширение MetaMask для Google Chrome. MetaMask ― это программный криптовалютный кошелек c открытым исходным кодом, используемый для взаимодействия с блокчейном Ethereum. Он позволяет пользователям получить доступ к своему кошельку Ethereum через расширение браузера или мобильное приложение, которое затем можно использовать для взаимодействия с децентрализованными приложениями.
MetaMask работает на основе ассиметричных алгоритмов шифрования. Открытый и закрытый ключ генерируются при регистрации и в последующем хранятся на компьютере. При помощи закрытого ключа пользователь может восстановить доступ к своему кошельку в случае потери пароля. То есть при использовании такой технологии пользователь защищен от возможности кражи аккаунта путем получения злоумышленниками доступа к email адресу или смс сообщениям. Также стоит отметить, что при потере закрытого ключа пользователь навсегда теряет доступ к кошельку. Закрытый ключ представляет собой последовательность из 12 слов на английском языке несвязанных между собой.
Таким образом проанализировав, принципы работы был разработан следующий алгоритм аутентификации пользователя:
1. проверка наличия расширения MetaMask в браузере пользователя;
2. получение адреса кошелька MetaMask;
3. получение одноразового кода для пользователя с текущим адресом;
4. подписание кода при помощи закрытого ключа в MetaMask;
5. валидация на стороне сервера полученной подписи;
6. генерация нового одноразового кода.
Реализуемый алгоритм использует функции управления закрытыми ключами для создания подписи, подтверждающей, что пользователь владеет этим конкретным адресом Ethereum.
Если пользователь может доказать что владеет этим адресом Ethereum, он может войти в приложение с этим адресом в качестве уникального идентификатора для своей учетной записи. Это достигается путем использования цифровой подписи.
Цифровая подпись, предоставленная пользователем с использованием его закрытого ключа, позволит убедиться, что он контролирует его без необходимости раскрытия закрытого ключа.
Получить адрес MetaMask кошелька можно при помощи метода из библиотеки Web3.js eth_requestAccounts [1]:
ethereumProvider.request({ method: 'eth_requestAccounts' });
Теперь можно получить одноразовый ключ, отправив запрос на сервер. Для подписания ключа можно воспользоваться методом personal_sign. Он принимает два параметра это hex представление подписываемого сообщения и адрес кошелька MetaMask:
await ethereum.request({
method: 'personal_sign',
params: [
`0x${this.toHex(response.nonce)}`,
ethereum.selectedAddress,
],});
При попытке подписания будет предложено ознакомиться с подписываемыми данными и источником запроса, также в левом углу отображается текущий аккаунт.
Рисунок 1. Запрос подписи
После подписание на стороне сервера необходимо провести валидацию подписи. Пример запроса в формате JSON:
address: "0x***************"
signature: "0x876c7217f22f55cbad3ab70c071c4322cc5e7a45750c086277742a053b4142be508bde31a155ab1d17e0 da6212bfa67ddabe74ce1b0ee4d081aa10a3a582598e1c"
Для валидации подписи используется библиотека web3j (Java). Метод sign вычисляет специфичную для Ethereum подпись с помощью:
sign(keccak256("\x19Ethereum Signed Message:\n" + len(code) + code))) [2]
Добавление префикса к коду делает рассчитанную подпись распознаваемой как подпись, специфичную для Ethereum. Это предотвращает неправомерное использование, когда вредоносное DApp может подписывать произвольные данные (например, транзакцию) и использовать подпись, чтобы выдать себя за жертву [3].
Таким образом получение hash-а одноразового кода выглядит следующим образом:
String prefix = "\u0019Ethereum Signed Message:\n" + code.length();
byte[] msgHash = Hash.sha3((prefix + code).getBytes());
Теперь нужно получить hash подписи:
byte[] signatureBytes = Numeric.hexStringToByteArray(signature);
byte v = signatureBytes[64];
if (v < 27) {v += 27;}
Sign.SignatureData sd = new Sign.SignatureData(v, Arrays.copyOfRange(signatureBytes, 0, 32), Arrays.copyOfRange(signatureBytes, 32, 64));
После того как был получен hash подписанного кода и подписи используя метод Sign.recoverFromSignature() можно получить все публичные ключи, подходящие для текущей подписи. Остается только сравнить полученные публичные ключи с адресом аккаунта для которого был сгенерирован одноразовый код. Если валидация подписи прошла успешно, обновляем код в базе данных.
Основные проблемы при использовании способа аутентификации через сторонние системы (социальные сети):
- пользователь доверяет сайту свои персональные данные, что может привести к их утечке;
- сайт хочет использовать внешнюю систему аутентификации, чтобы избежать хранения пользовательских данных и связанных с этим затрат на обеспечение безопасности.
- возможность цензуры и бана в сторонней системе, что приведет к потере аккаунта.
Представленный в данной статье механизм аутентификации имеет следующие достоинства в сравнении с традиционными способами аутентификации через логин/пароль и социальные сети:
- Безопасность. аутентификация с помощью шифрования с открытым ключом является более безопасным, чем аутентификация по логину/паролю или социальные сети, поскольку MetaMask хранит учетные данные локально на вашем компьютере, а не на онлайн-серверах, что делает поверхность атаки меньше [3];
- Скорость. Данный способ работает быстрее чем аутентификации через социальную сеть и является более простым в использовании;
- Конфиденциальность. Не используются почта и внешние системы.
Но также у данного способа есть свои недостатки:
- Необходимость установить MetaMask. Данное расширение имеет узкую специализацию и предназначено для тех, кто интересуется криптовалютой;
- Нет реализации из “коробки”. Реализация данного способа потребует изменения во всех областях, которые используются для аутентификации;
- Невозможно использовать на мобильных устройствах введу отсутствия поддержки плагинов.
Список литературы:
- Amaury Martiny One-click Login with Blockchain: A MetaMask Tutorial / [Электронный ресурс]. - Режим доступа: URL: https://www.toptal.com/ethereum/one-click-login-flows-a-metamask-tutorial (дата обращения: 20.04.2022).
- JSON RPC Ethereum wiki / [Электронный ресурс]. - Режим доступа: URL: https://github.com/ethereum/wiki/wiki/JSON-RPC (дата обращения: 20.04.2022).
- Как реализовать функцию входа в систему одним ключом DAPP после авторизации подписи MetaMask? / [Электронный ресурс]. - Режим доступа: URL: https://russianblogs.com/article/9338287813/ (дата обращения: 20.04.2022).
- Делаем web-аутентификацию через блокчейн / [Электронный ресурс]. - Режим доступа: URL: https://habr.com/ru/post/423039/ (дата обращения: 20.04.2022).