Переходите к безопасной 2FA на блокчейне

СМС-сообщения — популярнейший способ двухфакторной аутентификации (2FA). Ее используют банки, электронные и крипто-кошельки, почтовые ящики и всяческие сервисы; число пользователей метода приближается к 100%.

У меня такой расклад событий вызывает негодование, ведь этот метод небезопасный. Переназначать номер с одной SIM-карты на другую стали еще в начале мобильной эры — так восстанавливают номер при потере симки. “Специалисты по отъему цифровых денег” осознали: опцию «перезаписи симки» можно использовать в мошеннических схемах. Ведь тот, кто контролирует сим-карту, может управлять и чужим онлайн-банкингом, и электронными кошельками, и даже криптовалютой. А завладеть номером другого лица можно через подкуп сотрудника телекома, с помощью обмана или поддельных документов.

Переходите к безопасной 2FA на блокчейне

Раскрыты тысячи эпизодов SIM-свопинга — так назвали эту схему мошенничества. Масштабы бедствия говорят о том, что скоро мир откажется от 2FA по СМС. Но этого не происходит — в исследовании рассказывают, что выбирают метод 2FA не пользователи, а владельцы сервисов.

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

Счет идет на миллионы

В 2019 году мошенничество SIM-свопингом выросло на 63% по данным лондонской полиции, а “средний чек” злоумышленника — 4,000 GBP. Статистики в России я не нашел, однако предполагаю, что она еще хуже.

SIM-свопинг используется для кражи популярных аккаунтов Twitter, Instagram, Facebook, VK, банковских аккаунтов, а недавно добрались и до криптовалют — сообщает газета Таймс со слов биткоин-предпринимателя Джоби Уикса. Громкие дела о краже криптовалют с помощью SIM-свопинга всплывают в прессе с 2016 года; на 2019-й пришелся настоящий пик.

В мае прокуратура США в восточном округе Мичигана предъявила обвинения девяти молодым людям в возрасте от 19 до 26 лет: они предположительно входят в хакерскую банду под названием “The Community” («Сообщество»). Банде вменяется семь свопинг-атак, в результате которых хакеры присвоили криптовалюту на сумму свыше $2,4 миллиона. А в апреле студент из Калифорнии Джоэл Ортиз получил 10 лет тюрьмы за SIM-свопинг; его добычей стали $7.5 млн. в криптовалютах.

Переходите к безопасной 2FA на блокчейне
Фото Джоэла Ортиза на пресс-конференции в университете. Спустя два года он будет задержан за кибермошенничество.

Принцип работы SIM-свопинга

«Свопинг» — значит обмен. Во всех подобных схемах преступники присваивают себе телефонный номер жертвы, обычно через перевыпуск SIM-карты, и пользуются им для сброса пароля. Типичный SIM-свопинг в теории выглядит так:

  1. Разведка. Мошенники узнают персональные данные жертвы: имя и телефон. Их можно найти в открытых источниках (соцсети, друзья) или получить от сообщника — сотрудника сотового оператора.
  2. Блокировка. SIM-карта жертвы деактивируется; для этого достаточно позвонить в техподдержку провайдера, сообщить номер и сказать, что телефон был утерян.
  3. Захват, перевод номера на свою симку. Обычно это тоже делается через сообщника в телеком-компании либо с помощью подделки документов.

В реальной жизни все еще более сурово. Злоумышленники выбирают жертву, а затем ежедневно отслеживают местонахождение телефона — один запрос на получение информации о том, что абонент перешел в роуминг стоит 1-2 цента. Как только владелец сим-карты уехал за границу, они договариваются с менеджером в салоне связи на выдачу новой сим-карты. Стоит это около $50 (я находил информацию — в разных странах и у разных операторов от $20 до $100), при этом менеджер в худшем случае будет уволен — за это нет ответственности.

Теперь все СМС будут получать злоумышленники, а владелец телефона ничего не сможет с этим сделать — он за границей. А дальше злодеи получают доступ ко всем аккаунтам жертвы и при желании меняют пароли.

Шансы вернуть украденное

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

Если пострадавшие хотят отстоять свои деньги в суде, то обвиняют оператора: он создал условия для кражи денег со счета. Именно так поступил Майкл Терпин, который потерял из-за свопинга $224 млн. Сейчас он судится с телекоммуникационной компанией AT&T.

Переходите к безопасной 2FA на блокчейне

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

SIM-свопинг — не единственная проблема 2FA через СМС

Коды подтверждения в СМС небезопасны и с технической точки зрения. Сообщения можно перехватить из-за неустранимых уязвимостей в сигнальной системе Signaling System 7 (SS7). 2FA по SMS официально признана небезопасной (Национальный институт стандартов и технологий США говорит об этом в своем Руководстве по цифровой аутентификации).

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

А еще нередко СМС приходят с большой задержкой или не приходят совсем.

Другие способы 2FA

Разумеется, на смартфонах и СМС свет клином не сошелся. Есть и другие способы 2FA. Например, одноразовые TAN-коды: способ примитивный, но рабочий — он до сих пор используется в некоторых банках. Есть системы с применением биометрических данных: отпечатков пальцев, сканов сетчатки. Еще один вариант, который кажется разумным компромиссом по удобству, надежности и цене — специальные приложения для 2FA: RSA Token, Google Authenticator. А еще есть физические ключи и другие методы.

В теории все выглядит логичным и надежным. Но на практике у современных 2FA-решений есть проблемы, и из-за них реальность отличается от ожиданий.

Согласно исследованию, использование 2FA является неудобством в принципе, а популярность 2FA по СМС объясняют “меньшим неудобством по сравнению с другими методами” — получение одноразовых кодов понятно для пользователя.

Многие способы 2FA пользователи связывают со страхом, что доступ будет утерян. Физический ключ или список TAN-паролей можно потерять или их могут украсть. У меня лично есть негативный опыт использования Google Authenticator. Первый смартфон с этим приложением у меня сломался — оцените мои труды по восстановлению доступа к аккаунтам. Другая проблема — переход на новое устройство. Google Authenticator не имеет возможности экспорта из-за соображений безопасности (если ключи можно экспортировать, какая тут безопасность?). Один раз я переносил ключи вручную, а дальше решил, что проще оставлять старый смартфон в коробке на полке.

Метод 2FA должен быть:

  • Безопасным — получить доступ к аккаунту должны только вы, а не злоумышленники
  • Надежным — вы получаете доступ к аккаунту всегда, когда это нужно
  • Удобным и доступным — использование 2FA понятно и занимает минимум времени
  • Дешевым

Мы считаем, что блокчейн — подходящее решение.

Используйте 2FA на блокчейне

Для пользователя 2FA на блокчейне выглядит так же, как и получение одноразовых кодов по СМС. Отличие только в канале доставки. Способ получения 2FA-кода зависит от того, что предлагает блокчейн. В нашем проекте (информация есть в моем профиле) это Web-приложение, Tor, iOS, Android, Linux, Windows, MacOS.

Сервис генерирует одноразовый код и посылает его в мессенджер на блокчейне. Дальше — по классике: пользователь вводит полученный код в интерфейсе сервиса и авторизуется.

Переходите к безопасной 2FA на блокчейне

В статье Как работает децентрализованный мессенджер на блокчейне я написал, что блокчейн обеспечивает безопасность и приватность передачи сообщений. По вопросу отправки кодов 2FA я выделю:

  • Один клик для создания аккаунта — никаких телефонов и электронных почт.
  • Все сообщения с кодами 2FA шифруются End-to-End curve25519xsalsa20poly1305.
  • MITM-атака исключена — каждое сообщение с кодом 2FA является транзакцией в блокчейне и подписывается Ed25519 EdDSA.
  • Сообщение с кодом 2FA попадает в свой блок. Последовательность и timestamp блоков не исправишь, а следовательно и порядок сообщений.
  • Нет центральной структуры, которая делает проверки на “достоверность” сообщения. Это делает распределенная система узлов на основе консенсуса, а она принадлежит пользователям.
  • Невозможность отключения — аккаунты нельзя блокировать, а сообщения удалять.
  • Доступ к кодам 2FA с любого устройства в любое время.
  • Подтверждение доставки сообщения с кодом 2FA. Сервис, отправляющий одноразовый пароль, точно знает, что он доставлен. Никаких кнопок “Отправить еще раз”.

Для сравнения с некоторыми другими методами 2FA я составил таблицу:

Переходите к безопасной 2FA на блокчейне

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

Есть и неудобство — аккаунт должен иметь хотя бы одну транзакцию. Для того, чтобы пользователь получил шифрованное сообщение с кодом, нужно знать его публичный ключ, а он появляется в блокчейне только с первой транзакцией. Мы выкрутились так: дали возможность получить в кошельке бесплатные токены. Однако более правильное решение — именовать аккаунт публичным ключом. (Для сравнения у нас номер аккаунта U1467838112172792705 является производным публичного ключа cc1ca549413b942029c4742a6e6ed69767c325f8d989f7e4b71ad82a164c2ada. Для мессенджера это удобнее и читабельнее, а вот для системы отправки 2FA-кодов — ограничение). Думаю, в будущем кто-нибудь сделает такое решение и переведет “Удобство и доступность” в зеленую зону.

Цена отправки 2FA-кода реально низкая — 0.001 ADM, сейчас это 0.00001 USD. Опять же, можно поднять свой блокчейн и сделать цену нулевой.

Как подключить 2FA на блокчейне к вашему сервису

Надеюсь, я смог заинтересовать нескольких читателей, чтобы добавить блокчейн-авторизацию на их сервисы.

Я расскажу как это сделать на примере нашего мессенджера, а по аналогии вы можете использовать и другой блокчейн. В демо-приложении 2FA мы используем postgresql10 для хранения информации об аккаунтах.

Этапы подключения:

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

1 Создание аккаунта

Создание аккаунта в блокчейне — это генерация приватного ключа, публичного ключа, и производного от него адреса аккаунта.

Переходите к безопасной 2FA на блокчейне

Сначала генерируется пассфраза BIP39, из нее считается SHA-256-хэш. Хэш используется для генерации приватного ключа ks и публичного ключа kp. Из публичного ключа тем же SHA-256 с инверсией получаем адрес в блокчейне.

Если вы хотите отправлять коды 2FA каждый раз с нового аккаунта, код для создания аккаунта нужно будет добавить на сервер:

import Mnemonic from 'bitcore-mnemonic'
this.passphrase = new Mnemonic(Mnemonic.Words.ENGLISH).toString()

…

import * as bip39 from 'bip39'
import crypto from 'crypto'

adamant.createPassphraseHash = function (passphrase) {
  const seedHex = bip39.mnemonicToSeedSync(passphrase).toString('hex')
  return crypto.createHash('sha256').update(seedHex, 'hex').digest()
}

…

import sodium from 'sodium-browserify-tweetnacl'

adamant.makeKeypair = function (hash) {
  var keypair = sodium.crypto_sign_seed_keypair(hash)
  return {
    publicKey: keypair.publicKey,
    privateKey: keypair.secretKey
  }
}

…

import crypto from 'crypto'

adamant.getAddressFromPublicKey = function (publicKey) {
  const publicKeyHash = crypto.createHash('sha256').update(publicKey, 'hex').digest()
  const temp = Buffer.alloc(8)
  for (var i = 0; i < 8; i++) {
    temp[i] = publicKeyHash[7 - i]
  }
  return 'U' + bignum.fromBuffer(temp).toString()
}

В демо-приложении мы упростили — создали один аккаунт в веб-приложении, и отправляем коды с него. В большинстве случаев это удобнее и пользователю: он знает, что сервис отправляет 2FA-коды с конкретного аккаунта, и может его именовать.

Переходите к безопасной 2FA на блокчейне

2 Генерация кодов 2FA

Код 2FA нужно генерировать для каждого входа пользователя. Мы используем библиотеку speakeasy, но вы можете выбрать любую другую.

const hotp = speakeasy.hotp({
  counter,
  secret: account.seSecretAscii,
});

Проверка валидности кода 2FA, введенного пользователем:

se2faVerified = speakeasy.hotp.verify({
  counter: this.seCounter,
  secret: this.seSecretAscii,
  token: hotp,
});

3 Отправка кода 2FA

Для отправки 2FA-кода можно использовать API узла блокчейна, библиотеку JS API или консоль. В этом примере мы используем консоль — это Command Line Interface, утилита, которая упрощает взаимодействие с блокчейном. Чтобы отправить сообщение с 2FA-кодом, нужно использовать команду send message консоли.

const util = require('util');
const exec = util.promisify(require('child_process').exec);

…

const command = `adm send message ${adamantAddress} "2FA code: ${hotp}"`;
let { error, stdout, stderr } = await exec(command);

Альтернативный способ отправки сообщений — использовать метод send в JS API library.

4 Интерфейс пользователя

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

Переходите к безопасной 2FA на блокчейне

Исходный код демонстрационного приложения двухфакторной авторизации на блокчейне можно посмотреть в GitHub. В Readme есть ссылка на Live demo, чтобы попробовать.

Источник: habr.com