MTProto — криптографический протокол, используемый в системе обмена сообщениями Telegram для шифрования сообщений и обмена данных. Протокол был разработан Николаем Дуровым и другими программистами Telegram.
В основе протокола лежит оригинальная комбинация симметричного алгоритма шифрования AES (в режиме IGE), протокола Диффи-Хеллмана для обмена 2048-битными RSA-ключами между двумя устройствами и ряда хеш-функций. Протокол допускает использование шифрования end-to-end с опциональной сверкой ключей[1][2].
Также на основе протокола был создан MTProxy.
Создание сессий
правитьРегистрация устройства
правитьПри первом запуске приложения пользователь вводит номер своего телефона, на который приходит пятизначный код его подтверждения[3].
После ввода кода приложение запускает протокол авторизации[4]:
- Клиент С отправляет запрос на сервер S со строкой, составленной из случайной 128-битной последовательности.
- S отправляет в ответ другую случайную 128-битную последовательность, число n (64-битное) и цифровую подпись публичного ключа RSA (получаемую из младших 64 бит SHA1-хэша публичного ключа сервера).
- C раскладывает n на два простых числа p и q так, что p < q, и это служит проверкой работы. У клиента есть набор публичных ключей сервера, хранящийся на устройстве. Из него C выбирает ключ , подходящий для пришедшей подписи с сервера S.
- C выбирает другую случайную 256-битную строку, отличающуюся от предыдущей строки клиента и сервера. Клиент собирает набор из трех случайных строк, чисел n, p и q, шифрует его с помощью ключа по алгоритму RSA и отправляет на сервер S.
- S отвечает с параметрами g, p, протокола Диффи-Хеллмана, зашифрованными алгоритмом AES-256 в режиме IGE, используя временный ключ и Salt, получаемую из новой строки клиента и сервера.
- C выбирает закрытый ключ b, вычисляет открытый ключ и общий открытый ключ . Затем (в зашифрованном виде) отправляется на сервер S[4].
Создание секретного чата между двумя пользователями
правитьПользователи A и B хотят инициализировать секретный чат[5]:
- A соединяется с сервером, чтобы получить параметры для протокола Диффи-Хеллмана — простое p и генератор g. A также получает для генерации секретного ключа a.
- A вычисляет открытый ключ и отправляет его пользователю B.
- B получает запрос на создание чата и подтверждает его инициализацию только на одном из его авторизованных устройств. Он подключается к серверу для получения последних параметров протокола Диффи-Хэлмана и генерирует свой закрытый ключ b.
- B вычисляет открытый ключ и отправляет его A.
- Оба пользователя генерируют общий открытый ключ . На этом обмен секретными ключами между пользователями окончен[5].
Примечания
править- Секретный ключ a генерируется по правилу: , где 2048 бит, сгенерированные генератором случайных чисел на устройстве клиента, — 2048 бит сгенерированные сервером для того, чтобы в случае ненадежного генератора у пользователя усилить стойкость ключа a.
- Оба клиента проверяют, что сервер прислал им безопасное простое число p (такое что также является простым), число и генерирует циклическую подгруппу по простому основанию . Параметры p и q, получаемые от сервера, фиксированы и могут меняться только между версиями приложения[6].
Шифрование сообщений
правитьLength | Header | Random bits | Layer | seq_in | seq_out | Header | Random id | TTL | Message | Header | Padding | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
32 bit | 32 bit | 128 bit | 32 bit | 32 bit | 32 bit | 32 bit | 64 bit | 32 bit | Произвольная длина | 32 bit | 0-96 bit | |||
Блок 1 | Блок 2 | Блок 3 | Блок 4 | Блоки | Блок N |
- Length — длина пакета без учёта padding
- Header — каждый пакет состоит из трех заголовков, содержащих информацию о версии протокола, типе приложенных медиафайлов
- Random bits — 120 бит, сгенерированных клиентом, и 8 бит определяют длину поля в байтах. Используется как Salt для шифрования
- Layer — обозначает версию протокола
- seq_in — количество отправленных сообщений к создателю чата
- seq_out — количество отправленных сообщений от создателя чата
- Random id — произвольное число, сгенерированное отправляющим клиентом, отправляется как текст
- TTL — число секунд, в течение которых получатель сможет видеть сообщение перед его удалением
- Message — сообщение, введенное пользователем (произвольной длины)
- Padding — добавляется непосредственно перед шифрованием
Схема шифрования
править- auth_key — открытый ключ шифрования, полученный при создании чата
- Payload — пакет для шифрования (из предыдущего пункта)
- msg_key — младшие 128 бит SHA1-хэша шифруемого пакета. Используется для проверки корректности при расшифровании
- Padding — 0—96 бит, добавленных для того, чтобы размер блока для шифрования был равен 128 битам
- AES key и IV — параметры для шифрования алгоритмом AES в режиме IGE. Получены с помощью KDF
- KDF (key derivation function) — функция формирования AES key и IV на основе msg_key и auth_key
- auth_key_id — младшие 64 бит SHA1-хэша открытого ключа K. В случае коллизии открытый ключ будет сгенерирован снова[7]
Расшифрование сообщений
правитьauth_key_id | msg key | Encrypted Data |
---|---|---|
64 бит | 128 бит | N * 128 бит |
- Клиент получает зашифрованное сообщение, проверяет подлинность auth_key_id — вычисляет младшие 64 бит SHA1-хеша открытого ключа K. В случае совпадения значений продолжается расшифровка сообщения
- С помощью key derivation function формируются AES key и IV
- Далее происходит поблочное дешифрование данных с помощью алгоритма AES-IGE. В итоге получаем пакет, который должен совпадать с пакетом отправителя.
- Сравниваем младшие 128 бит SHA1-хэша расшифрованного пакета с пришедшим msg_key. В итоге получаем расшифрованное сообщение[8].
Атаки на протокол
правитьЗеркальная атака и атака повтором
правитьДо 16-й версии протокола клиенты были вынуждены доверять серверу сохранять порядковые номера сообщений, а сами сообщения не обладали подобным механизмом. Но это означало, что сервер злоумышленника имел полный контроль над потоком сообщений. Сервер не имел возможности читать передаваемую информацию, но мог удерживать сообщения, менять их порядок, отправлять их снова. В случае, если хотя бы один из клиентов использует протокол версии 16 и ниже, чат является незащищенным от такого типа атак[9].
Timing-атака
правитьДанный вид атаки использует временной интервал между отправкой сообщения и приемом ответа об ошибке. Большинство пользователей Telegram использует его на мобильных устройствах со слабым сигналом, по этой причине проверка подлинности сообщений замедляется (время, за которое процессор обработает информацию, много меньше времени её получения)[9].
В Telegram проверки проходят в следующем порядке:
- Полученный auth_key_id сравнивается с хранящимся на устройстве.
- После дешифрования длина полученного сообщения должна быть больше 0 и меньше количества полученных байт.
- Вычисляется msg_key и сравнивается с полученным.
- Проверяются порядковые номера сообщений с локальным счетчиком.
Процесс дешифрования моментально прерывается в случае выявления ошибки.
Для осуществления атаки необходимо отправить сообщение в секретном чате, но зашифрованный пакет заменить на случайную последовательность. В результате проверок получатель не подтверждает получения сообщения и в окне отправителя данное сообщение навсегда останется непрочитанным[10].
Криптоанализ
правитьПо данным публикаций, протокол не имеет ни authenticated encryption (AE), ни indistinguishability under chosen-ciphertext attack (INDCCA)[1][2].
Атака #1 (с увеличением длины сообщения)
правитьК сформированному шифротексту , который дешифруется в сообщение , добавляется ещё один блок длиной 128 бит, то есть принимаемый шифротекст . В итоге преобразованное сообщение расшифровывается в виде , в котором , причем длина больше длины блока. Так как длина не проверяется, дешифрование сообщения пройдет успешно[1][11].
Для предотвращения данного типа атаки необходимо лишь проверять длину блока padding, в случае превышения допустимого размера необходимо прекращать дешифрование сообщения[1][12].
Атака #2 (с изменением последнего зашифрованного блока)
правитьВ сформированном шифротексте , который дешифруется в сообщение , изменяется последний блок длиной 128 бит, то есть принимаемый шифротекст . В итоге преобразованное сообщение расшифровывается в виде , причем длина равна длине . С вероятностью дешифрованное сообщение совпадает с оригинальным, но так как максимальная длина добавочного блока составляет 96 бит, то вероятность составляет , таким образом данный вид атаки получается намного более сложным, чем ожидалось[1][13].
Чтобы предотвратить данный тип атаки, необходимо добавить тег проверки padding в заголовки отправляемого сообщения, но исправления в протоколе не позволят пользователям с новым протоколом обмениваться сообщениями с пользователями, у которых остался старый[1][14].
Библиотеки для языков программирования
правитьНазвание | Язык(и) | Исходный код | Описание |
---|---|---|---|
@mtproto/core | JavaScript | https://github.com/alik0211/mtproto-core | Telegram API (MTProto) client library for browser |
MadelineProto | PHP | https://github.com/danog/MadelineProto | Async PHP client/server API for the telegram MTProto protocol |
Telethon | Python | https://github.com/LonamiWebs/Telethon | Pure Python 3 MTProto API Telegram client library, for bots too! |
pyrogram | Python | https://github.com/pyrogram/pyrogram | Telegram MTProto API Client Library and Framework for Python |
grammers | Rust | https://github.com/Lonami/grammers | A set of Rust libraries to interact with Telegram’s API |
TLSharp | C# | https://github.com/sochix/TLSharp | Telegram client library implemented in C# |
TDLib | Python, JavaScript, Go, Java, Kotlin, C#, C++, Swift, Objective-C, Dart, Delphi, Rust, Erlang, PHP, Lua, Ruby, Clojure, Emacs Lisp, D, Elixir, 1С, C, FPC | https://github.com/tdlib/td | Cross-platform library for building Telegram clients. It can be easily used from almost any programming language |
MTProto | Go | https://github.com/xelaj/mtproto | Full-native implementation of MTProto protocol on Golang! |
Примечания
править- ↑ 1 2 3 4 5 6 Security of MTProto, 2016.
- ↑ 1 2 Сryptanalysis of the Telegram messaging protocol.
- ↑ Сryptanalysis of the Telegram messaging protocol, с. 32.
- ↑ 1 2 Сryptanalysis of the Telegram messaging protocol, с. 32—34.
- ↑ 1 2 Сryptanalysis of the Telegram messaging protocol, с. 34—36.
- ↑ Сryptanalysis of the Telegram messaging protocol, с. 35.
- ↑ Сryptanalysis of the Telegram messaging protocol, с. 37—41.
- ↑ Сryptanalysis of the Telegram messaging protocol, с. 41—43.
- ↑ 1 2 Сryptanalysis of the Telegram messaging protocol, с. 51.
- ↑ Сryptanalysis of the Telegram messaging protocol, с. 51—52.
- ↑ Сryptanalysis of the Telegram messaging protocol, с. 47.
- ↑ Сryptanalysis of the Telegram messaging protocol, с. 48.
- ↑ Сryptanalysis of the Telegram messaging protocol, с. 49.
- ↑ Сryptanalysis of the Telegram messaging protocol, с. 50.
Литература
править- Jakob Bjerre Jakobsen. On the CCA (in)Security of MTProto. — 2016. — ISBN 978-1-4503-4564-4.
- A practical cryptanalysis of the Telegram messaging protocol . Дата обращения: 24 февраля 2017. Архивировано из оригинала 14 января 2016 года.
Ссылки
править- https://core.telegram.org/mtproto
- https://web.archive.org/web/20161129083141/https://unhandledexpression.com/2013/12/17/telegram-stand-back-we-know-maths/
- https://www.incibe.es/extfrontinteco/img/File/intecocert/EstudiosInformes/INT_Telegram_EN.pdf
Для улучшения этой статьи желательно:
|