Szimmetrikus titkosító algoritmusok

Az előző cikk folytatásaként HTTPS protokolt szeretnénk majd használni a kommunikációhoz. Ehhez azonban jobban meg kell ismerni a HTTPS protokolt, amihez pedig tisztába kell lenni a kriptográfia alapelemeivel. E célból kósolunk most bele a szimmetrikus titkosító algoritmusokba.

Naív titkosírás

Titkosírással kódolt üzeneteket már évezredek óta küldözgetnek egymásnak emberek. Ezek természetesen adódó, és egyszerű módszerek voltak, jellemzően valamilyen titkos abc-re/jelrendszerre, vagy a betűk helyének cserélgetésére épültek. Közös hátrányuk volt, hogy jó nyelvismerettel és egy kis türelemmel visszafejthetőek voltak. Ezek miatt egyre bonyolultabb algoritmusokat kezdtek használni a szöveg betűinek átkódolására/átmozgatására. Ezeknek a bonyolultabb algoritmusoknak azonban még mindig maradt egy közös gyenge pontja – ha az algoritmus valahogy kiszivárgott, onnantól az összes üzenetet meg lehetett fejteni.

Így jelentek meg a paraméterezhető titkosító algoritmusok, ahol az algoritmuson kívül egy kulcsot lehet megadni a titkosításhoz/visszafejtéshez. Ebben az esetben, ha valaki ismeri is az algoritmust, a kulcs ismerete nélkül nem tudja visszafejteni az üzenetet. A mai titkosító algoritmusok egy jó része is erre az elvre épül. Ma már általános szabály, hogy az algoritmus titkos voltára nem építenek, sőt, inkább a széles körben agyon analizált algoritmusok számítanak megbízhatónak.

Az algoritmus fontossága

Jó titkosító algoritmust nem olyan könnyű kitalálni. Hogy milyen hibái lehetnek egy algoritmusnak, egy egyszerű példán fogjuk megnézni. Valószínűleg többen ismerik az XOR műveletre épülő “titkosítást”. Erről ismert, hogy komoly célra nem illik használni, azonban ritkán mutatják meg, hogy miért nem. Hogy megízleljük a témát, és hogy világos legyen miért nem szabad önállóan titkosító algoritmusok fejlesztésébe kezdeni, megnézzük hogyan fejthető vissza egy XOR titkosító. Adott hát a következő titkosító algoritmus

public byte[] XorEncrypt(byte[] plainText, byte[] key)
{
    var cipherText = new byte[plainText.Length];

    for (var i = 0; i < plainText.Length; i++)
    {
        cipherText[i] = (byte)(plainText[i] ^ key[i % key.Length]);
    } // for i

    return cipherText;
} // XorEncrypt()

Próbáljuk ki egy 128 bites véletlenszámgenerátorral készített kulccsal (hogy később össze lehessen hasonlítani más modern titkosító algoritmussal, ami hasonló kulcsméretet használ):

var key = new byte[16];
random.NextBytes(key);

var result = XorEncrypt(Encoding.UTF8.GetBytes(testText), key);

A teszt szöveg a Lorem ipsum lesz, az eredmény pedig a következő:

Az eddigiek alapján akár meggyőzőnek is tűnhet. Egy gyakorlottabb szem azonban ránézésre kiszúr bizonyos mintákat. Pirossal jelöltem, hogy kicsit hunyorítva mit kell nézni:

Ha ez még mindig zavaros, nézzük meg másképpen ábrázolva:

Mit kell nézni? Hát a sok függőlegesen kirajzolódó csíkot. Nyilvánvalóan ez a kódolt üzenet tulajdonságaiból adódik, és meg is fogjuk nézni, mik ezek a tulajdonságok. Az ábra egyébként 128 bitet ábrázol egy sorban, ami a kulcsméretnek felel meg. Miért rajzolódnak ki a függőleges csíkok? Hogy megértsük, figyelembe kell venni, hogy a titkosított adat itt egy szöveg volt, ami ASCII kód alapján a latin abc karaktereiből épül fel. Az ASCII tábla a latin kisbetűket, a 0x61-es kódtól ábrázolja, aminek a bináris reprezentációban így néz ki:

0110 0001
0110 0010
0110 0011
0110 0100
...

Azt látjuk tehát, hogy az első négy bit mindig ugyanúgy néz ki. Az XOR titkosítás ezeket a biteket vagy átbillenti, vagy nem, de 128 bitenként itt mindig ugyanaz fog állni. És mivel tudjuk, hogy a legfelső bitnek nullának kell lenni, akkor ha a titkosított adat itt nullát tartalmaz, akkor a kulcs ide való bitje is nulla, egyébként egy. Ezzel a módszerrel a kulcs felét már meg is fejtettük (minden 8 bites blokkból 4 bitet). De nem kell sokat erőlködni a másik feléhez sem, ehhez azonban nézzük az ábra egy jobban előkészített változatát:

Ez az előző ábra bal felső sarka kinagyítva. Mit látunk rajta? Nézzük a legelső byte reprezentációját (az első nyolc pöttyöt, illetve pötty hiányát. Egy kék sáv 4 bitet tartalmaz) Látszik, hogy a harmadik bit itt nulla, a többi (az oszlopban alatta levő) hellyel ellentétben. Miért lehet ez így? Ez a szöveg első betűje, ami nagybetű. A nagybetűk pedig az ASCII tábla 0x41-es értékénél kezdődnek, ami binárisan:

0100 0001

Tehát a harmadik bit tényleg különbözik a kisbetűkétől. De az ábrán nem ezek érdekesek most. Találni viszonylag gyakori előfordulással egy teljesen más, az adott oszlopból kilógó mintát, ezek az pirossal bekarikázott elemek. Mik lehetnek ezek? Hát mik vannak gyakran egy szövegben: szóközök. A szóköz kódja 0x20. Miért érdekes ez? Azért mert ha tudjuk mi a szóköz, akkor tudjuk az adott oszlop mind a nyolc eredeti bitjének az értékét, amiből vissza tudjuk fejteni a kulcs adott byte-ját. Az első oszlopban a szóköz kódolt értéke:

0011 1000

Míg kódolatlanul:

0010 0000

Ebből pedig az XOR működését ismerve következik, hogy a kulcs első byte-ja

0001 1000 = 0x18

A második oszlopban ugyanígy megtaláljuk a szóközöket, ugyanezzel a módszerrel megtudjuk, hogy a kulcs második byte-ja 0x71. Ezt folytathatjuk, amíg nincs meg a kulcs mind a 16 byte-ja, ezután pedig visszafejthetjük a kulcs ismeretében az egész szöveget. Pusztán tehát “szemmel veréssel” pár perc alatt visszafejtettünk egy hobbi-titkosítást.

Modern titkosító algoritmusok

Mostanra látjuk, hogy egy rossz tulajdonságokkal bíró titkosító algoritmussal kódolt adatot mennyire egyszerű lehet visszafejteni. Mi volt a baj? Hogy a kódolt adaton nagyon sok információt lehetett találni az eredeti szövegre vonatkozólag. Egy jó titkosító algoritmus látszólag véletlenszerű értékeket generál. A titkosítandó adat apró változtatására is véletlenszerűen változik az eredmény, és nem enged statisztikai alapon következtetéseket levonni a titkosított adatról. Nézzünk egy példát. Az alábbi ábra az XOR titkosítással kódolt adat változásait mutatja, ha a kódolandó szöveg egy karakterét elkezdjük az abc-ben rákövetkező betűre kicserélni (Ami egy bitnyi változást jelent a titkosítandó adaton). A kódolandó adat tehát:

AAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAB
AAAAAAAAAAAAAAAC
AAAAAAAAAAAAAAAD

Az eredmény grafikusan ábrázolva pedig XOR esetén:

Érdemes megnézni mit művel egy modern titkosító algoritmus (Ebben az esetben AES, aki ért hozzá, ECB módban futott, tehát nem a CBC miatt más minden sor)

Bár a szemünk kiszúrhat látszólagos egyezőségeket, például a található nagyságrendileg tíz függőleges vonal. Azonban 128 bit esetén négy bitsorozatnál annak az esélye, hogy adott pozícióban mind a 4 bit 1-es lesz, az 1:8, tehát statisztikailag ez rendben van. Mivel általában az embereknek hamis elképzelése van a véletlenszerű bitsorozatokról, például kicsi valószínűséget tulajdonítanak 7-8 hosszúságú azonos értéksornak, álljon itt egy véletlen bitsorozat, hogy lehessen mihez hasonlítani:

Így talán könnyebb elfogadni, az AES valóban jól keveri a biteket, a legapróbb változtatásra is. Ezek az algoritmusok a titkosítandó adat tartalmától, illetve a használt kulcstól függetlenül látszólag véletlenszerűen adnak vissza egy bitsorozatot. Az XOR titkosítás egyik baja az volt, hogy a titkosítandó adat bitjeinek eloszlása látszódott a titkosított adaton. Az AES ezt elkerüli.

A blokkos titkosítások korlátai

Az AES, és több más, általánosan használt titkosító algoritmus blokkos működésű. Ez azt jelenti, hogy a titkosítást az adaton blokkonként végzik. A blokk mérete algoritmustól függ, régebben a 64 bit hosszú blokkok voltak jellemzőek (pl 3DES), ma 128-256 bites blokkmérettel is működnek algoritmusok. A titkosítás közben a bitek egy “blokkon belül kavarognak”, és ennek van egy csúnya következménye.

Titkosítsunk olyan adatot, ami 4 darab, 16 byte-os (128 bites) blokkból tevődik össze, és minden blokk tartalma ugyanaz:

var plainText =
        "Pro-C#-ryptology" +
        "Pro-C#-ryptology" +
        "Pro-C#-ryptology" +
        "Pro-C#-ryptology";

AES-sel kódolva a következő eredményt kapjuk:

Bár arra nem jönnénk rá, milyen adat van egy blokkon belül, az nagyon szépen látszik, hogy a titkosítandó adat 4 darab ugyanolyan blokkból áll, ami viszont nem szerencsés, még azt figyelembe véve sem, hogy ez egy kiélezett példa. Egy másik látványos példa található ugyanerre a jelenségre a Wikipédián. Mivel a pingvin háttere fehér, ezen pixelek kódolása ugyanaz, emiatt szépen kirajzolódik a nem-fehér, illetve más, nagy tömegben azonos színek.

Még csúnyább dolog, hogy egy titkosított adafolyamban ezek a blokkok felcserélhetőek, és ha valami szerencsétlen összjátékként az adatstruktúra ezzel a cserével sértetlen marad, a vevő nem fog rájönni a manipulációra. Nézzünk egy átutalást leíró adatstruktúrát (most véletlenül minden mező 16 byte, és a számlaszámok is 16 byte-ok)

var plainText =
       "atutalas HUF/HUF" +
       "2223334445556667" +
       "9966554433221123" +
       "350'000'000  HUF" 

Ekkor az AES-sel titkosított adat a következőképpen néz ki:

Ha megcserélünk két blokkot (a két középső sor lett felcserélve):

És ezt dekódoljuk, az eredmény a következő:

A két “számlaszám” tehát ki lett cserélve a titkosítás ellenére.

Blokk láncolás

Az előző példákban két gonddal találkoztunk. Az egyik, hogy azonos adattartalommal bíró blokkok azonos eredményt adnak azonos kulcs használatával, és ez felfed információkat a titkosított adatról. A másik gond, hogy a blokkok sorrendiségét semmi nem jelöli, így a titkosított adat blokkjait cserélgethetjül, törölhetjük, vagy akár egy régebbi, ugyanazzal a kulccsal titkosított adatból szeleteket emelhetünk át.

Ezeknek a problémáknak a kiküszöbölésére vezették be az úgynevezett blokk láncolást (Cipher-block chaining, CBC). Ebben az esetben, amikor egy blokk titkosításra kerül, nem közvetlenül a titkosított blokkra fut le a titkosító algoritmus, hanem a titkosítandó blokkon előbb az előzőleg titkosított blokkot felhasználva egy műveletet, mégpedig az XOR műveletet hajtják végre. Könnyebb megérteni a folyamatot az alábbi ábra alapján (az adatok nem igaziak, csak a billentyűzetre tenyereltem):

Adva van tehát a korábbi példa titkosítandó blokkja, ami most is a “Pro-C#-ryptology” szöveg. (1). Mielőtt azonban ezt titkosítanánk, egy másik, a blokkméretnek megfelelő adattal (2) egy XOR műveletet hajtunk végre. Ez az adat egyébként az előző titkosított blokk, illetve a legelső blokk esetére mindjárt visszatérünk. A két adattal végrehajtott XOR létrehoz egy harmadik adatblokkot (3), és most ezen hajtódik végre az titkosító művelet, természetesen egy megfelelő kulcsot használva (a kulcs nincs jelölve az ábrán). A titkosítás eredménye egy szokásos bináris zanza (4)

A következő blokk titkosításához felhasználjuk a most titkosított blokkot (5). Ennek a blokknak a titkosításakor, bár a titkosítandó adat ugyanúgy a “Pro-C#-ryptology”, mivel más értékkel képezzük az XOR eredményét, ennél a blokknál más lesz a titkosító eljárás bemenete (6), és így a kimenete is (7)

Kérdés, hogy mit használunk a legelső blokk kódolásánál, hiszen ott nem lehet felhasználni az előző blokk eredményét. Ehhez egy Initialization Vector (IV)-nak nevezett értéket használnak. Hogy ennek mi az értéke, attól függ, hogyan használják a titkosító eljárást. Ha huzamosabb ideig, több alkalommal használnak egy kulcsot, akkor az IV értékét jellemzően egy véletlen érték adja. Ekkor a titkosított üzenet fogadójának az IV-t is meg kell kapnia, hiszen a dekriptálásnál az XOR műveleteket szintén végre kell hajtani, hogy az eredeti adatot megkapjuk. Ekkor az IV-t a titkosított adattal el kell küldeni. Több helyen láttam már, hogy ezt az IV-t is próbálják védeni, mintha ez a titkos kulcs része lenne. Ez azonban felesleges, az IV ismerete semmit nem segít az üzenet megfejtésében. (Illetve ha más is el van rontva, akkor az IV ismerete segítheti a támadást, lásd Padding Oracle Attack bizonyos formái. Hogy ne csak papírkutyálkodjunk, a következő cikkben csinálunk egy ilyet)

Ha a kulcsokat csak egyszer használják (pl mert valamilyen kulcs csere protokollal azt csak egy alkalomra generálják), akkor az IV értékét gyakran egy csupa nulla értékből álló vektornak veszik. Ez semmit nem gyengít a CBC értékén. Az egyik szerepe a CBC-nek, hogy az azonos értékű blokkok más és más enkriptált eredményt adjanak. Ha a kezdő blokk mindig ugyanaz, az IV szintén, akkor a titkosítás mindig ugyanazon az értéken kezdődik. Azonban a kulcs csere protokoll mindig más kulcsot generál, emiatt a végeredmény mindig más lesz – emiatt lehet nyugodan használni konstans nulla IV-t.

Padding

Eddig mindig akkora adattal dolgoztunk, amekkora az adott titkosító eljárás blokkmérete, például 128 bit. Titkosítani azonban nem mindig 128 bit, vagy n * 128 bit hosszú adatot szeretnénk. Mivel a blokkos működésű titkosítások csak teljes hosszúságú blokkon működnek, amennyiben a titkosítandó adat nem ilyen hosszú, azt ki kell egészíteni.

A kiegészítést több módon lehet végezni. Vannak olyan esetek, amikor a titkosítandó adat szerkezete olyan, hogy nem változik a jelentése, ha mögé egyéb adatok kerülnek, azok úgysem lesznek figyelembe véve. A WINApi-ban például számtalan olyan struktúra van, amelynek első 4 byte-ja (egy unsigned int formájában) megadja a struktúra byte-okban kifejezett méretét. Ekkor, ha egy ilyen jellegű struktúrát titkosítunk, nyugodtan mögé tehetünk feltöltő byte-okat, például nullákat.

Más esetekben a titkosítandó adat nem tartalmaz saját magára vonatkozó információkat a szerkezetéről, emiatt a feltöltést úgy kell elvégezni, hogy az utána egyértelműen el lehessen távolítani. Erre az egyik módszer például, ha a titkosított blokk elé egy számot (pl 4 byte-on ábrázolva) írunk az eredeti adat hosszával, majd az adatot kipótoljuk, hogy megfeleljen a blokkméretet. Ebben az esetben a visszafejtésnél pontosan ismerni kell, hogy milyen módon lett az adat blokkméretre igazítva, hiszen az eljárást visszafele is el kell végezni.

Ezt a blokkméretre igazítást padding-nak hívják, a .NET többféle megoldást támogat. Ezeket nem veszem sorra, mivel nagyszerűen le van írva az MSDN-en

Szimmetrikus titkosítás C#-ban

A .NET Crypto API-ja szörnyen rosszra sikerült, amikor pár éve komolyabban kellett volna dolgoznom vele, inkább rászántam két hetet, és írtam egy normálisat C#-ban, a Windows CryptoAPI-jára építve. A szimmetrikus résszel foglalkozó API szerencsére még a legkevésbé rossz, ezzel fogunk most alap szinten megismerkedni.

A központi osztály a SymmetricAlgorithm, ezen találjuk meg azokat a műveleteket és property-ket, amelyeket a szimmetrikus titkosító algoritmusok általában tudnak. A SymmetricAlgorithm megvalósítja az IDisposable interfészt, ami egy algoritmus esetében furcsának tűnhet. Azért van ez így, mert a megvalósítások egy része a Windows CryptoAPI-ra épül, ami viszont HANDLE-kel dolgozik, amelyeket fel kell szabadítani használat után. A Windows CryptoAPI egyébként plug-in jelleggel működik, emiatt símán lehet, hogy egy hardveres eszköz (például smart kártya) van a titkosító eljárás alatt, így még érthetőbb az IDisposable szerepe.

A fontos property-k értelmét mostanra könnyen kitaláljuk a SymmetricAlgorithm osztályon. A Key a titkosításhoz szükséges kulcs, figyelembe kell venni az algoritmust a kulcs méreténél. Némelyik algoritmus (mint az AES) többféle kulcsméretet támogat. Az IV az inicializáló vektor, mint láttuk blokk láncolásnál van szerepe. A blokk láncolást a Mode property-n adhatjuk meg, a láncolás nélküli (ECB), és az egyszerű blokk láncoláson (CBC) kívül egyéb láncolási módok is támogatottak. Végül a Padding, melyből szintén több típus támogatott.

Maga a SymmetricAlgorithm factory-ként is működik, paraméterként adhatjuk meg, hogy milyen titkosító algoritmust akarunk használni. Egy titkosító algoritmus beállítása a következőképpen történhet:

using (var symmetricAlgorithm = SymmetricAlgorithm.Create("AES"))
{
    var key = new byte[16];
    var iv = new byte[16];

    random.NextBytes(key); 
    random.NextBytes(iv); 

    symmetricAlgorithm.BlockSize = 128;
    symmetricAlgorithm.Key = key;
    symmetricAlgorithm.IV = iv;
    symmetricAlgorithm.Mode = CipherMode.CBC;
    symmetricAlgorithm.Padding = PaddingMode.PKCS7;

    ...
} // using

Hogy milyen stringeket fogad a SymmetricAlgorithm.Create(), megtalálható a CryptoConfig osztály leírásánál az MSDN-en. Alternatívaként létrehozhatjuk magunk a kívánt típusú példányt:

using (var aesAlgorithm = new AesCryptoServiceProvider())
{
...
} // using

Némi kényelmi szolgáltatás, hogy a leszármazott osztályok tudnak a beállításoknak megfelelő kulcsot/IV-t generálni, így ezzel nem kell nekünk bajlódni:

symmetricAlgorithm.GenerateKey();
symmetricAlgorithm.GenerateIV();

Amikor a paraméterek be vannak állítva, kezdődhet a titkosítás/visszafejtés. A titkosítás/visszafejtés műveletet a .NET CryptoAPI egy interfész mögé absztrahálta, aminek a neve ICryptoTransform. A SymmentricAlgorithm példánytól kell a célnak megfelelő ICryptoTransform megvalósítást kérni, amely így vagy titkosítani, vagy visszafejteni tud:

var cryptoTransform = symmetricAlgorithm.CreateEncryptor();

Az ICryptoTransfrom szintén IDisposable, erre figyelni kell. A két fő művelete a TransformBlock() illetve a TransformFinalBlock(). A TransformBlock-ot akkor használjuk, ha a titkosítandó/visszafejtendő adat nagyon nagy, vagy nem áll egyben rendelkezésre. Ezt ciklusban hívogatva tudjuk használni, azonban figyelni kell rá, hogy az ECB blokk láncolási módot leszámítva az adaton csak az elejétől kezdve, folytonosan lehet hívogatni, mivel a blokk láncoláshoz szükséges belső állapotot karbantartja (nem lehet tehát dekódolni vele csak az adat közepét például). A TransformFinalBlock() annyival tud többet a TransformBlock()-nál, hogy odailleszti/leszedi a padding-ot az adat végére/végéről.

Egy komplett kódolási folyamat tehát így néz ki:

var textToBeCiphered = "Hol volt, hol nem volt, volt egyszer egy nagy király";

byte[] key = null;
byte[] iv = null;

byte[] cipherText = null;

using (var symmetricAlgorithm = SymmetricAlgorithm.Create("AES"))
{
    symmetricAlgorithm.BlockSize = 128;
    symmetricAlgorithm.GenerateKey();
    symmetricAlgorithm.GenerateIV();
    symmetricAlgorithm.Mode = CipherMode.CBC;
    symmetricAlgorithm.Padding = PaddingMode.PKCS7;

    var bytesToBeCiphered = Encoding.UTF8.GetBytes(textToBeCiphered);

    using (var transformation = symmetricAlgorithm.CreateEncryptor())
    {
        cipherText 
            = transformation.TransformFinalBlock(
                    bytesToBeCiphered, 0, bytesToBeCiphered.Length);
    } // using

    key = symmetricAlgorithm.Key;
    iv = symmetricAlgorithm.IV;
} // using

Console.WriteLine(BitConverter.ToString(cipherText));

string plainText = null;

using (var symmetricAlgorithm = SymmetricAlgorithm.Create("AES"))
{
    symmetricAlgorithm.BlockSize = 128;
    symmetricAlgorithm.Key = key;
    symmetricAlgorithm.IV = iv;
    symmetricAlgorithm.Mode = CipherMode.CBC;
    symmetricAlgorithm.Padding = PaddingMode.PKCS7;

    using (var transformation = symmetricAlgorithm.CreateDecryptor())
    {
        var deciphered
            = transformation.TransformFinalBlock(
                    cipherText, 0, cipherText.Length);

        plainText = Encoding.UTF8.GetString(deciphered);
    } // using

    Console.WriteLine(plainText);
} // using

Valójában a Mode és Padding paramétereknek a fent beállítottak a default paraméterei, így azok akár el is hagyhatóak. A BlockSize méretét pedig minden leszármazott típus megfelelően beállítja. Emiatt a fenti kód rövidebben is leírható:

using (var symmetricAlgorithm = SymmetricAlgorithm.Create("AES"))
{
    using (var transformation = symmetricAlgorithm.CreateDecryptor(key, iv))
    {
        var deciphered
            = transformation.TransformFinalBlock(
                    cipherText, 0, cipherText.Length);

        plainText = Encoding.UTF8.GetString(deciphered);
    } // using

Biztonságosak a szimmetrikus algoritmusok?

A széles körben használt titkosító eljárások biztonságosnak tekinthetők, azonban nagyon könnyű hibásan alkalmazni őket, ami támadási felületet adhat. Nem is olyan nehéz kiszúrni, hogy hol lehetnek rossz implementációk. Tipikus amatőr gyakorlat például, hogy mindenből a legnagyobbat használják, azaz AES 256 bites kulccsal, SHA512-n alapuló HMAC, stb. Ha ilyet látunk, akkor vagy évszázadokra akarnak biztosítani valamit, vagy nem értette a rendszer tervezője, hogy mit miért csinál, így jó eséllyel hibát vétett valahol. Hogy lássuk milyen könnyű elrontani valamit, a következő cikkben bemutatok egy támadási módot egy rosszul implementált szervizzel szemben.

Bizalmasság vs integritás

Egy jellemző félreértés, hogy a titkosítás egyben véd az adat módosítása ellen is. Láthattuk, hogy egy ECB (amikor nincs blokk láncolás) kódolt adat milyen egyszerűen manipulálható a titkosítás ellenére is. De a CBC mód sem véd a módosítás ellen. Lehet, hogy módosítás után az adat értelmetlenné válik, de sokszor nem is cél az értelmes adat. Sok rendszert ki lehet gyilkolni, ha sikerül értelmetlen adatot bejuttatni. Ha egy program írója bízik a titkosított adat integritásában, és feltétel nélkül elhisz minden értéket, komoly gondjai lesznek 7483796547 byte lefoglalásánál. Van, hogy egy módosítás nem is detektálható olyan könnyen. Ha a titkosított adatok csak lebegőpontos számpárok, mondjuk koordináták, komoly analizálás szükséges, hogy kiszúrjuk, értelmes adatok jönnek be, vagy pedig egy belenyúlt bit miatt a visszafejtett adat most véletlenszerű lebegőpontos értékeket tartalmaz.

Emiatt, ha az integritást akarjuk védeni, külön kriptografikus eljárásokat kell alkalmazni. Ezekről szó lesz egy későbbi cikkben.

  1. #1 by eMeL on 2012. April 7. - 12:45

    Köszi, ritka érthetően foglaltad össze.
    Még az első elméleti blokkban is találtam újdonságot és nem aludtam bele (ami túl elvont, a valóságtól elrugaszkodott elméleti szövegeknél előfordul).

  1. A szimmetrikus titkosítás megvéd? Nem, ha rosszul használod! - pro C# tology - devPortal

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: