End-to-End-kryptering, hemmelige Chats

denne artikel om Mtprotos end-to-End-kryptering er beregnet til avancerede brugere.Hvis du vil lære mere om hemmelige Chats fra en mindre skræmmende kilde, se venligst vores generelle ofte stillede spørgsmål.

Bemærk, at fra version 4.6 bruger store Telegram-klienter MTProto 2.0.MTProto v. 1. 0 er forældet og er ved at blive udfaset.

Hemmelige Chats er en-til-en-chats, hvor meddelelser krypteres med en nøgle, der kun holdes af chatens deltagere. Bemærk, at skemaet for disse end-to-end krypterede Hemmelige Chats er forskelligt fra det, der bruges til cloud-chats:

en note om MTProto 2.0

denne artikel beskriver end-to-end krypteringslaget i MTProto protocol version 2.0.De vigtigste forskelle fra version 1.0 (beskrevet her som reference) er som følger:

  • SHA-256 bruges i stedet for SHA-1;
  • Padding bytes er involveret i beregningen af msg_key;
  • msg_key afhænger ikke kun af meddelelsen, der skal krypteres, men også af en del af den hemmelige chatnøgle;
  • 12..1024 polstring bytes bruges i stedet for 0..15 polstring bytes i v. 1. 0.

Se også: MTProto 2.0: Cloud Chats, server-klient kryptering

nøglegenerering

nøgler genereres ved hjælp af Diffie-Hellman-protokollen.

lad os overveje følgende scenario: bruger A vil gerne starte end-to-end krypteret kommunikation med bruger B.

afsendelse af en anmodning

bruger A udfører meddelelser.getDhConfig for at opnå Diffie-Hellman-parametrene: en prime p og et højordenselement g.

udførelse af denne metode før hver ny nøglegenereringsprocedure er af afgørende betydning. Det giver mening at cache værdierne for parametrene sammen med versionen for at undgå at skulle modtage alle værdierne hver gang. Hvis den version, der er gemt på klienten, stadig er opdateret, returnerer serveren konstruktørmeddelelserne.dhconfignotmodificeret.

klient forventes at kontrollere, om p er en sikker 2048-bit prime (hvilket betyder, at både p og (p-1)/2 er prime, og at 2^2047< p< 2^2048), og at g genererer en cyklisk undergruppe af prime order (p-1) / 2, dvs. er en kvadratisk rest mod S. DA g altid er lig med 2, 3, 4, 5, 6 eller 7, gøres dette let ved hjælp af kvadratisk gensidighedslov, hvilket giver en simpel betingelse for p mod 4G-nemlig p mod 8 = 7 for G = 2; p mod 3 = 2 For g = 3; ingen ekstra betingelse for G = 4; p mod 5 = 1 eller 4 for G = 5; p mod 24 = 19 eller 23 for G = 6; og p mod 7 = 3, 5 eller 6 for g = 7. Efter at g og p er blevet kontrolleret af klienten, er det fornuftigt at cache resultatet for at undgå at gentage lange beregninger i fremtiden. Denne cache kan deles med en, der bruges til generering af Autorisationsnøgler.

hvis klienten har en utilstrækkelig tilfældig talgenerator, er det fornuftigt at passere random_length-parameteren (random_length> 0), så serveren genererer sin egen tilfældige sekvens tilfældig af den passende længde.Vigtigt: brug af serverens tilfældige sekvens i sin rå form kan være usikker. Det skal kombineres med en klientsekvens, for eksempel ved at generere et klient tilfældigt tal af samme længde (client_random) og bruge final_random := random XOR client_random.

klient a beregner et 2048-bit nummer A (ved hjælp af tilstrækkelig entropi eller serverens tilfældige; se ovenfor) og udfører meddelelser.anmodning om kryptering efter at have passeret g_a := pow(g, a) mod dh_prime.

bruger B modtager opdateringsopdateringskryptering for alle tilknyttede autorisationsnøgler (alle autoriserede enheder) med chatkonstruktøren encryptedchatanmodet. Brugeren skal have vist grundlæggende oplysninger om Bruger A og skal blive bedt om at acceptere eller afvise anmodningen.

begge klienter skal kontrollere, at g, g_a og g_b er større end en og mindre end p-1. Vi anbefaler at kontrollere, at g_a og g_b er mellem 2^{2048-64} og p – 2^{2048-64} også.

accept af en anmodning

Når bruger B bekræfter oprettelsen af en hemmelig chat med A i klientgrænsefladen, modtager klient B også opdaterede konfigurationsparametre for Diffie-Hellman-metoden. Derefter genererer det et tilfældigt 2048-bit tal, b, ved hjælp af regler svarende til dem for a.

efter at have modtaget g_a fra opdateringen med encryptedchatanmodet, kan den straks generere den endelige delte nøgle:key = (pow(g_a, b) mod dh_prime). Hvis nøglelængde < 256 bytes, Tilføj flere førende nul byte som polstring — så nøglen er nøjagtigt 256 bytes lang. Dens fingeraftryk, key_fingerprint, er lig med de 64 sidste bits af SHA1 (nøgle).

Note 1: i dette særlige tilfælde bruges SHA1 her selv til MTProto 2.0 hemmelige chats.

Note 2: dette fingeraftryk bruges som en sanity check for nøgleudvekslingsproceduren for at opdage fejl ved udvikling af klientprogram — det er ikke forbundet med den nøglevisualisering, der bruges på klienterne som middel til ekstern godkendelse i hemmelige chats. Nøglevisualiseringer på klienterne genereres ved hjælp af de første 128 bit SHA1(intial key) efterfulgt af de første 160 bit SHA256(nøgle, der blev brugt, da secret chat blev opdateret til lag 46).

klient B udfører meddelelser.acceptEncryption efter at have passeret det g_b := pow(g, b) mod dh_prime og key_fingerprint.

for alle Client B ‘ s autoriserede enheder, undtagen den nuværende, sendes updateEncryption-opdateringer med constructor encryptedChatDiscarded. Derefter er den eneste enhed, der kan få adgang til den hemmelige chat, enhed B, der ringede til beskeder.acceptEncryption.

bruger A vil blive sendt en updateEncryption-opdatering med constructor encryptedChat, for den autorisationsnøgle, der startede chatten.

Med g_b fra opdateringen kan klient A også beregne den delte nøglekey = (pow(g_b, a) mod dh_prime). Hvis nøglelængde < 256 bytes, Tilføj flere førende nul byte som polstring — så nøglen er nøjagtigt 256 bytes lang. Hvis fingeraftrykket for den modtagne nøgle er identisk med det, der blev sendt til encryptedChat, indgående meddelelser kan sendes og behandles. Ellers meddelelser.kassekryptering skal udføres og brugeren underrettes.

perfekt Fremadhemmelighed

for at holde tidligere kommunikation sikker, vil officielle Telegram-klienter starte genindtastning, når en nøgle er blevet brugt til at dekryptere og kryptere mere end 100 meddelelser eller har været i brug i mere end en uge, forudsat at nøglen er blevet brugt til at kryptere mindst en meddelelse. Gamle nøgler kasseres derefter sikkert og kan ikke rekonstrueres, selv med adgang til de nye nøgler, der i øjeblikket er i brug.

re-keying-protokollen er yderligere beskrevet i denne artikel: perfekt Fremadhemmelighed i hemmelige Chats.

bemærk, at din klient skal understøtte Fremadhemmelighed i hemmelige Chats for at være kompatibel med officielle Telegram-klienter.

afsendelse og modtagelse af meddelelser i en hemmelig Chat

serialisering og kryptering af udgående meddelelser

et tl-objekt af typen dekrypteret besked oprettes og indeholder meddelelsen i almindelig tekst. For bagudkompatibilitet skal objektet pakkes ind i konstruktøren dekrypteretmessagelag med en indikation af det understøttede lag (begyndende med 46).

TL-skemaet for indholdet af end-to-end krypterede meddelelser er tilgængeligt her “

den resulterende konstruktion er serialiseret som en række bytes ved hjælp af generiske tl-regler. Det resulterende array forberedes med 4 bytes, der indeholder array-længden, der ikke tæller disse 4 bytes.

byte-arrayet er polstret med 12 til 1024 tilfældige polstring bytes for at gøre længden delelig med 16 bytes. (I den ældre MTProto 1.0-kryptering blev der kun brugt 0 til 15 polstring byte.)

Meddelelsesnøgle, msg_key, beregnes som de 128 midterste bits af SHA256 af de data, der blev opnået i det foregående trin, forudindstillet med 32 bytes fra den delte nøgletast. (For den ældre MTProto 1.0-kryptering blev msg_key beregnet forskelligt som de 128 lavere bit SHA1 af de data, der blev opnået i de foregående trin, eksklusive polstringbytes.)

for MTProto 2.0 beregnes AES-tasten aes_key og initialiseringsvektoren aes_iv (nøgle er den delte nøgle opnået under nøglegenerering ) som følger:

  • msg_key_large = SHA256 (substr (nøgle, 88 + gange, 32) + klartekst + random_padding);
  • msg_key = substr (msg_key_large, 8, 16);
  • sha256_a = SHA256 (msg_key + substr (nøgle, 36));
  • sha256_b = SHA256 (substr (nøgle, 40+gange, 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);

for MTProto 2.0, n=0 for meddelelser fra ophavsmanden til den hemmelige chat, h=8 for meddelelserne i den modsatte retning.

for den forældede MTProto 1.0, msg_key, aes_key og aes_iv blev beregnet forskelligt (se dette dokument som reference).

Data krypteres med en 256-bit nøgle, aes_key og en 256-bit initialiseringsvektor, AES-iv, ved hjælp af AES-256-kryptering med uendelig garble-udvidelse (ige). Krypteringsnøgle fingerprint key_fingerprint og meddelelsesnøglen msg_key tilføjes øverst i det resulterende byte-array.

krypterede data er indlejret i en meddelelse.sendEncrypted API opkald og videre til Telegram server til levering til den anden part i den hemmelige Chat.

opgradering til MTProto 2.0 fra MTProto 1.0

så snart begge parter i en hemmelig chat bruger mindst Layer 73, bør de kun bruge MTProto 2.0 til alle udgående meddelelser. Nogle af de første modtagne meddelelser bruger muligvis MTProto 1.0, hvis der ikke er forhandlet et tilstrækkeligt højt startlag under oprettelsen af den hemmelige chat. Når den første meddelelse, der er krypteret med MTProto 2.0 (eller den første meddelelse med lag 73 eller højere) er modtaget, skal alle meddelelser med højere sekvensnumre også krypteres med MTProto 2.0.

så længe det aktuelle lag er lavere end 73, skal hver part forsøge at dekryptere modtagne meddelelser med MTProto 1.0, og hvis dette ikke lykkes (msg_key stemmer ikke overens), skal du prøve MTProto 2.0. Når den første MTProto 2.0-krypterede meddelelse ankommer (eller laget er opgraderet til 73), er der ingen grund til at prøve MTProto 1.0 dekryptering for nogen af de yderligere meddelelser (medmindre klienten stadig venter på, at nogle huller lukkes).

dekryptering af en indgående meddelelse

ovenstående trin udføres i omvendt rækkefølge. Når en krypteret meddelelse er modtaget, skal du kontrollere, at msg_key er faktisk lig med de 128 midterste bits af SHA256 hash af den dekrypterede meddelelse, prepended af 32 bytes taget fra den delte nøgle.Hvis meddelelseslaget er større end det, der understøttes af klienten, skal brugeren underrettes om, at klientversionen er forældet og bliver bedt om at opdatere.

sekvensnumre

det er nødvendigt at fortolke alle meddelelser i deres oprindelige rækkefølge for at beskytte mod mulige manipulationer. Hemmelige chats understøtter en særlig mekanisme til håndtering af sekv_no-tællere uafhængigt af serveren.

korrekt håndtering af disse tællere er yderligere beskrevet i denne artikel: sekvensnumre i hemmelige Chats.

bemærk, at din klient skal understøtte sekvensnumre i hemmelige Chats for at være kompatibel med officielle Telegram-klienter.

afsendelse af krypterede filer

alle filer, der sendes til hemmelige chats, krypteres med engangsnøgler, der på ingen måde er relateret til chatens delte nøgle. Før en krypteret fil sendes, antages det, at den krypterede Fils adresse vil blive knyttet til ydersiden af en krypteret meddelelse ved hjælp af filparameteren for meddelelserne.sendEncryptedFile metode, og at nøglen til direkte dekryptering vil blive sendt i brødteksten i meddelelsen (nøgleparameteren i konstruktørerne decryptedMessageMediaPhoto, decryptedMessageMediaVideo og decryptedMessageMediaFile.

før en fil sendes til en hemmelig chat, beregnes 2 tilfældige 256-bit tal, som vil fungere som AES-tasten og initialiseringsvektoren, der bruges til at kryptere filen. AES-256 kryptering med uendelig garble udvidelse (IgE) bruges på samme måde.

nøglefingertrykket beregnes som følger:

  • digest = md5(key + iv)
  • fingerprint = substr(digest, 0, 4) substr(digest, 4, 4)

det krypterede indhold af en fil gemmes på serveren på samme måde som en fil i cloud chats: stykke for stykke ved hjælp af opkald til upload.Gem filepart.Et efterfølgende opkald til meddelelser.sendEncryptedFile tildeler en identifikator til den gemte fil og sender adressen sammen med meddelelsen. Modtageren modtager en opdatering med krypteretbesked, og filparameteren indeholder filoplysninger.

indgående og udgående krypterede filer kan videresendes til andre hemmelige chats ved hjælp af constructor inputEncryptedFile for at undgå at gemme det samme indhold på serveren to gange.

arbejde med en Opdateringsboks

hemmelige chats er forbundet med specifikke enheder (eller rettere med autorisationsnøgler), ikke brugere. En konventionel meddelelsesboks, der bruger pts til at beskrive klientens status, er ikke egnet, fordi den er designet til langvarig meddelelseslagring og meddelelsesadgang fra forskellige enheder.

en ekstra midlertidig meddelelseskø introduceres som en løsning på dette problem. Når en opdatering vedrørende en besked fra en hemmelig chat sendes, sendes en ny værdi af KTS, som hjælper med at rekonstruere forskellen, hvis der har været en lang pause i forbindelsen eller i tilfælde af tab af en opdatering.

efterhånden som antallet af begivenheder stiger, øges værdien af KVT ‘ er med 1 For hver ny begivenhed. Den oprindelige værdi må ikke (og vil ikke) være lig med 0.

det faktum, at begivenheder fra den midlertidige kø er modtaget og gemt af klienten, anerkendes eksplicit ved et opkald til meddelelserne.modtagetkø metode eller implicit ved et opkald til opdateringer.getDifference (værdien af KTS bestået, ikke den endelige tilstand). Alle meddelelser, der er anerkendt som leveret af klienten, samt alle meddelelser, der er ældre end 7 dage, kan (og vil) blive slettet fra serveren.

efter de-autorisation vil begivenhedskøen for den tilsvarende enhed blive fjernet med magt, og værdien af KVT ‘ er bliver irrelevant.

opdatering til nye lag

din klient skal altid gemme det maksimale lag, der vides at være understøttet af klienten på den anden side af en hemmelig chat. Når den hemmelige chat først oprettes, skal denne værdi initialiseres til 46. Denne fjernlagsværdi skal altid opdateres umiddelbart efter modtagelse af en pakke, der indeholder oplysninger om et øverste lag, dvs.:

  • enhver hemmelig chatbesked, der indeholder layer_no i dens decryptedMessageLayer med lag>=46, eller
  • en dekrypteretmessageactionnotifylayer servicemeddelelse, indpakket som om det var dekrypteretmessageservice-konstruktør af det forældede lag 8 (konstruktør decryptedMessageService#aa48327d).

underretning af fjernklienten om dit lokale lag

for at underrette fjernklienten om dit lokale lag skal din klient sende en besked af typendecryptedMessageActionNotifyLayer. Denne meddelelse skal pakkes ind i en konstruktør af et passende lag.

der er to tilfælde, hvor din klient skal underrette fjernklienten om sit lokale lag:

  1. så snart en ny hemmelig chat er oprettet, umiddelbart efter at den hemmelige nøgle er blevet udvekslet.
  2. umiddelbart efter at den lokale klient er blevet opdateret for at understøtte et nyt hemmeligt chatlag. I dette tilfælde skal meddelelser sendes til alle aktuelt eksisterende hemmelige chats. Bemærk, at dette kun er nødvendigt, når du opdaterer til nye lag, der indeholder ændringer i implementeringen af hemmelige chats (f. eks. du behøver ikke at gøre dette, når din klient opdateres fra lag 46 Til lag 47).

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.