tento článek o End-to-End šifrování MTProto je určen pro pokročilé uživatele.Pokud se chcete dozvědět více o tajných chatech z méně zastrašujícího zdroje, laskavě se podívejte na naše obecné FAQ.
Všimněte si, že od verze 4.6 používají hlavní klienti telegramu MTProto 2.0.MTProto v. 1. 0 je zastaralý a v současné době je vyřazován.
tajné chaty jsou individuální chaty, kde jsou zprávy šifrovány klíčem drženým pouze účastníky chatu. Všimněte si, že schéma pro tyto end-to-end šifrované Tajné Chaty je odlišné od toho, co se používá pro cloud chaty:
poznámka na MTProto 2.0
Tento článek popisuje, end-to-end šifrování vrstva v MTProto protokolu verze 2.0.Hlavní rozdíly oproti verzi 1.0 (zde popsané pro referenci) jsou následující:
- SHA-256 se používá místo SHA-1;
- Padding bajtů jsou zapojeny do výpočtu msg_key;
- msg_key závisí nejen na zprávy, které mají být šifrována, ale na část tajemství chatu klíč;
- 12..Místo 0 se používá 1024 polstrovacích bajtů..15 polstrování bytů v v. 1. 0.
Viz také: MTProto 2.0: Cloud Chaty, server-klient šifrování
Generování Klíčů
Klíče jsou generovány pomocí Diffie-Hellman protokol.
uvažujme následující scénář: Uživatel A by chtěl zahájit end-to-end šifrovanou komunikaci s uživatelem B.
odeslání požadavku
uživatel a provede zprávy.getDhConfig pro získání parametrů Diffie-Hellman: prvočíslo p a prvek vysokého řádu g.
provedení této metody před každou novou procedurou generování klíčů má zásadní význam. Má smysl ukládat hodnoty parametrů do mezipaměti spolu s verzí, aby se zabránilo tomu, že budete muset pokaždé přijímat všechny hodnoty. Pokud je verze uložená v klientovi stále aktuální, server vrátí zprávy konstruktoru.dhconfignot změněn.
Klient očekává se, že zkontrolovat, zda p je bezpečný 2048-bit prime (což znamená, že oba p a (p-1)/2 jsou prvočísla, a že 2^2047 < p < 2^2048), a to g generuje cyklickou podskupina vlády řádu (p-1)/2, tj. je kvadratický zbytek mod p. Protože g je vždy roven 2, 3, 4, 5, 6 nebo 7, je to snadno provést pomocí kvadratické reciprocity zákon, dávat jednoduché podmínky, na p mod 4g-jmenovitě, p mod 8 = 7 pro g = 2; p mod 3 = 2 pro g = 3; žádné další podmínkou pro g = 4; p mod 5 = 1 nebo 4 pro g = 5; p mod 24 = 19 nebo 23 pro g = 6; a p mod 7 = 3, 5 nebo 6 Pro g = 7. Poté, co klient zkontroloval g a p, má smysl ukládat výsledek do mezipaměti, aby se v budoucnu zabránilo opakování zdlouhavých výpočtů. Tato mezipaměť může být sdílena s mezipamětí používaným pro generování autorizačního klíče.
Pokud má klient nedostatečné generátor náhodných čísel, to dává smysl, aby projít random_length parametr (random_length> 0), takže server si vytváří svůj vlastní náhodné sekvence náhodných odpovídající délky.Důležité: použití náhodné sekvence serveru v surové formě může být nebezpečné. Musí být kombinován s klientskou sekvencí, například generováním klientského náhodného čísla stejné délky (client_random) a použitím final_random := random XOR client_random
.
klient a vypočítá 2048bitové číslo a (pomocí dostatečné entropie nebo náhodného serveru; viz výše) a provede zprávy.requestEncryption po absolvování g_a := pow(g, a) mod dh_prime
.
Uživatel B obdrží aktualizaci updateEncryption pro všechny přidružené autorizační klíče (všechny autorizované zařízení) s chat konstruktor encryptedChatRequested. Uživateli musí být zobrazeny základní informace o uživateli A a musí být vyzván k přijetí nebo zamítnutí žádosti.
oba klienti mají zkontrolovat, že g, g_a a g_b jsou větší než jeden a menší než p-1. Doporučujeme zkontrolovat, zda g_a a g_b jsou také mezi 2^{2048-64} a p-2^{2048-64}.
přijetí požadavku
poté, co uživatel B potvrdí vytvoření tajného chatu s a v klientském rozhraní, klient B také obdrží aktuální konfigurační parametry pro metodu Diffie-Hellman. Poté vygeneruje náhodné 2048bitové číslo, b, pomocí pravidel podobných pravidlům pro a.
po obdržení g_a od aktualizace s encryptedChatRequested, může okamžitě generovat konečné sdílený klíč: key = (pow(g_a, b) mod dh_prime)
. Pokud délka klíče < 256 bajtů, přidejte několik předních nulových bajtů jako polstrování – takže klíč je přesně 256 bajtů dlouhý. Jeho otisk prstu, key_fingerprint, se rovná 64 posledním bitům SHA1 (klíč).
Poznámka 1: v tomto konkrétním případě se zde SHA1 používá i pro tajné chaty MTProto 2.0.
Poznámka 2: tento otisk se používá jako kontrola zdravého rozumu pro postup výměny klíčů k detekci chyb při vývoji klientského softwaru — není připojen k vizualizaci klíčů používané na klientech jako prostředek externí autentizace v tajných chatech. Klíčové vizualizace na klienty jsou generovány pomocí prvních 128 bitů, SHA1(intial klíč), následuje první 160 bitů SHA256(klíč použitý při tajné chat byl aktualizován, aby vrstva 46).
klient B provádí zprávy.acceptEncryption po předání g_b := pow(g, b) mod dh_prime
a key_fingerprint.
pro všechna autorizovaná zařízení klienta B, s výjimkou aktuálního, jsou aktualizace updateEncryption odesílány pomocí konstruktoru encryptedChatDiscarded. Poté je jediným zařízením, které bude mít přístup k tajnému chatu, zařízení B, které uskutečnilo volání na zprávy.přijměte šifrování.
uživateli A bude zaslána aktualizace updateEncryption s konstruktorem encryptedChat pro autorizační klíč, který inicioval chat.
S g_b z aktualizace může klient a také vypočítat sdílený klíč key = (pow(g_b, a) mod dh_prime)
. Pokud délka klíče < 256 bajtů, přidejte několik předních nulových bajtů jako polstrování – takže klíč je přesně 256 bajtů dlouhý. Pokud je otisk prstu pro přijatý klíč totožný s otiskem prstu, který byl předán encryptedChat, lze příchozí zprávy odesílat a zpracovávat. Jinak zprávy.discardEncryption musí být proveden a uživatel upozorněn.
Perfect Forward Secrecy
V zájmu zachování posledních komunikace bezpečný, oficiální Telegram klienti budou iniciovat re-klíčování jednou za klíč se používá k dešifrování a šifrování více než 100 zpráv, nebo byl v použití pro více než jeden týden za předpokladu, že klíč byl použit k zašifrování alespoň jednu zprávu. Staré klíče jsou pak bezpečně vyřazeny a nelze je rekonstruovat, a to ani s přístupem k novým klíčům, které se v současné době používají.
re-keying protokol je dále popsán v tomto článku: perfektní dopředné utajení v tajných chatech.
Vezměte prosím na vědomí, že váš klient musí podporovat utajení vpřed v tajných chatech, aby byl kompatibilní s oficiálními klienty telegramu.
Odesílání a Přijímání Zpráv v Tajné Chat
Serializace a Šifrování Odchozích Zpráv
TL objekt typu DecryptedMessage je vytvořen a obsahuje zprávu v prostém textu. Pro zpětnou kompatibilitu musí být objekt zabalen do konstruktoru decryptedMessageLayer s označením podporované vrstvy(počínaje 46).
TL-Schéma obsahu end-to-end šifrované zprávy je k dispozici zde „
výsledný konstrukt je serializován jako pole bajtů pomocí generic TL pravidla. Výsledné pole je prepended o 4 bajty obsahující délku pole nepočítaje tyto 4 bajty.
pole bajtů je vyplněno 12 až 1024 náhodnými polstrovacími bajty, aby byla jeho délka dělitelná 16 bajty. (Ve starším šifrování MTProto 1.0 bylo použito pouze 0 až 15 polstrovacích bajtů.)
klíč Zprávy, msg_key, je počítán jako 128 střední bitů SHA256 údajů získaných v předchozím kroku, před 32 bajtů od sdílený klíč. (Pro starší šifrování MTProto 1.0 byl msg_key vypočítán odlišně, jako 128 dolních bitů SHA1 dat získaných v předchozích krocích, s výjimkou polstrovacích bajtů.)
Pro MTProto 2.0, AES klíč aes_key a inicializační vektor aes_iv jsou počítány ( klíč je sdílený klíč získaný při Generování Klíčů ) takto:
- msg_key_large = SHA256 (substr (klíč, 88+x, 32) + plaintext + random_padding);
- msg_key = substr (msg_key_large, 8, 16);
- sha256_a = SHA256 (msg_key + substr (klíč, x, 36));
- sha256_b = SHA256 (substr (klíčový, 40+x, 36) + msg_key);
- aes_key = substr (sha256_a, 0, 8) + substr (sha256_b, 8, 16) + substr (sha256_a, 24, 8);
- aes_iv = substr (sha256_b, 0, 8) + substr (sha256_a, 8, 16) + substr (sha256_b, 24, 8);
Pro MTProto 2.0, x=0 pro zprávy od původce secret chat, x=8 pro zprávy v opačném směru.
pro zastaralé MTProto 1.0, msg_key, aes_key a aes_iv byly vypočteny odlišně (viz tento dokument).
Data jsou šifrována pomocí 256bitového klíče, aes_key a 256bitového inicializačního vektoru, AES-iv, pomocí šifrování AES-256 s infinite garble extension (IGE). Šifrovací klíč fingerprint key_fingerprint a klíč zprávy msg_key jsou přidány v horní části výsledného pole bajtů.
šifrovaná data jsou vložena do zprávy.sendEncrypted API volání a předán Telegram serveru pro doručení na druhou stranu tajného chatu.
upgrade na MTProto 2.0 z MTProto 1.0
jakmile obě strany v tajném chatu používají alespoň vrstvu 73, měly by používat pouze MTProto 2.0 pro všechny odchozí zprávy. Některé z prvních přijatých zpráv mohou používat MTProto 1.0, pokud během vytváření tajného chatu nebyla sjednána dostatečně vysoká počáteční vrstva. Po obdržení první zprávy šifrované pomocí MTProto 2.0 (nebo první zprávy s vrstvou 73 nebo vyšší) musí být všechny zprávy s vyššími pořadovými čísly šifrovány také pomocí MTProto 2.0.
Pokud je aktuální vrstva nižší než 73, každá strana by se měla pokusit dešifrovat přijaté zprávy pomocí MTProto 1.0, a pokud to není úspěšné (msg_key neodpovídá), zkuste MTProto 2.0. Jakmile první MTProto 2.0-zašifrovaná zpráva dorazí (nebo vrstva je aktualizován na 73), není třeba se snažit MTProto 1.0 dešifrování na kteroukoli další zprávy (pokud klient stále čeká na nějaké mezery, musí být uzavřen).
dešifrování příchozí zprávy
výše uvedené kroky se provádějí v opačném pořadí. Když se zašifrovaná zpráva je přijata, musíte zkontrolovat, že msg_key je ve skutečnosti rovná 128 střední kousky SHA256 hash dešifrovat zprávu, před 32 bajtů přijatých od sdílený klíč.Pokud je vrstva zpráv větší než vrstva podporovaná klientem, musí být uživatel upozorněn, že verze klienta je zastaralá, a vyzván k aktualizaci.
pořadová čísla
je nutné interpretovat všechny zprávy v původním pořadí, aby byla chráněna před možnými manipulacemi. Tajné chaty podporují speciální mechanismus pro zpracování čítačů seq_no nezávisle na serveru.
Správné manipulaci těchto čítačů je dále popsáno v tomto článku: pořadová čísla v Tajné Chaty.
Vezměte prosím na vědomí, že váš klient musí podporovat pořadová čísla v tajných chatech, aby byl kompatibilní s oficiálními klienty telegramu.
odesílání šifrovaných souborů
všechny soubory odeslané do tajných chatů jsou šifrovány jednorázovými klíči, které nijak nesouvisejí se sdíleným klíčem chatu. Před odesláním zašifrovaného souboru se předpokládá, že adresa zašifrovaného souboru bude připojena na vnější stranu šifrované zprávy pomocí parametru soubor zpráv.sendEncryptedFile metoda a že klíčové pro přímé dešifrování bude odeslán v těle zprávy (klíčovým parametrem v konstruktory decryptedMessageMediaPhoto, decryptedMessageMediaVideo a decryptedMessageMediaFile.
před odesláním souboru do tajného chatu se vypočítají 2 náhodná 256bitová čísla, která budou sloužit jako klíč AES a inicializační vektor používaný k šifrování souboru. AES-256 šifrování s infinite garble extension (IGE) se používá podobným způsobem.
otisk klíče se vypočte následovně:
- digest = md5(klíč + iv)
- fingerprint = substr(digest, 0, 4) XOR substr(digest, 4, 4)
šifrovaný obsah souboru jsou uloženy na serveru v podstatě stejným způsobem jako u souborů v cloudu chaty: kousek po kousku pomocí hovory, které chcete nahrát.zachraň část.Následné volání na zprávy.sendEncryptedFile přiřadí identifikátor uloženému souboru a odešle adresu spolu se zprávou. Příjemce obdrží aktualizaci s šifrovanýmzpráva a parametr soubor bude obsahovat informace o souboru.
Příchozí a odchozí šifrované soubory mohou být předány do další tajné chatování pomocí konstruktoru inputEncryptedFile, aby se zabránilo ukládání stejného obsahu na serveru dvakrát.
práce s aktualizačním polem
tajné chaty jsou spojeny s konkrétními zařízeními( nebo spíše s autorizačními klíči), nikoli s uživateli. Konvenční pole zpráv, které používá pts k popisu stavu klienta, není vhodné, protože je určeno pro dlouhodobé ukládání zpráv a přístup ke zprávám z různých zařízení.
jako řešení tohoto problému je zavedena další dočasná fronta zpráv. Při aktualizaci ohledně zprávu z tajné chatu je odeslána, nová hodnota qts je poslal, který pomáhá rekonstruovat rozdíl, jestli tam byla dlouhá přestávka v připojení, nebo v případě ztráty aktualizace.
Jak se počet událostí zvyšuje, hodnota qts se zvyšuje o 1 s každou novou událostí. Počáteční hodnota se nemusí (a nebude) rovnat 0.
skutečnost, že události z dočasné fronty byly přijaty a uloženy v klienta je uveden explicitně pomocí volání zprávy.metoda receivedQueue nebo implicitně voláním aktualizací.getDifference (hodnota qts prošla, ne konečný stav). Všechny zprávy potvrzené jako doručené klientem, stejně jako všechny zprávy starší než 7 dní, mohou být (a budou) odstraněny ze serveru.
po zrušení autorizace bude fronta událostí odpovídajícího zařízení násilně vymazána a hodnota qts bude irelevantní.
aktualizace na nové vrstvy
váš klient by měl vždy uložit maximální vrstvu, o které je známo, že ji klient podporuje, na druhé straně tajného chatu. Při prvním vytvoření tajného chatu by měla být tato hodnota inicializována na 46. Tato hodnota vzdálené vrstvy musí být vždy aktualizována ihned po obdržení jakéhokoli paketu obsahujícího informace o horní vrstvě, tj.:
- žádné tajné chat zprávy obsahující layer_no v jeho
decryptedMessageLayer
s vrstvou>=46, nebo - decryptedMessageActionNotifyLayer zprávy služby, zabalené, jako kdyby to byly decryptedMessageService konstruktoru zastaralé vrstvy 8 (constructor
decryptedMessageService#aa48327d
).
upozornění vzdáleného klienta na vaši lokální vrstvu
Chcete-li vzdálenému klientovi oznámit vaši lokální vrstvu, musí váš klient odeslat zprávu typu decryptedMessageActionNotifyLayer
. Toto oznámení musí být zabaleno do konstruktoru příslušné vrstvy.
Existují dva případy, kdy váš klient je povinen oznámit vzdáleného klienta o jeho místní vrstva:
- jakmile nový tajný chat byl vytvořen, ihned po tajný klíč byl úspěšně vyměněny.
- ihned po aktualizaci místního klienta na podporu nové vrstvy tajného chatu. V takovém případě musí být oznámení zaslána všem aktuálně existujícím Tajným chatům. Všimněte si, že je to nutné pouze při aktualizaci na nové vrstvy, které obsahují změny v implementaci tajných chatů (např. nemusíte to dělat, když je váš klient aktualizován z vrstvy 46 na vrstvu 47).