1. Kódování a hashování

Microsoft .NET obsahuje třídy rozšiřující kryptografické služby nabízené Windows CryptoAPI. Tyto třídy se nachází v jmenném prostoru System.Security.Cryptography a zahrnují

  • Symetrické kódování (kódování se symetrickým klíčem)

  • Asymetrické kódování (s asymetrickým klíčem)

  • Hashování (hashovací funkce)

  • Digitální certifikáty

  • XML podpisy

1.1. Symetrické kódování

[znalosti]

Algoritmy využívající symetrické kódování jsou velice rychlé a hodí se pro kódování velkého množství dat. Tyto algoritmy mohou data jak kódovat, tak i dekódovat. I když jsou vcelku bezpečné, pokud je k dispozici dost času, může být jejich šifra prolomena.

Symetrické kódování je v .NET implementováno pomocí tříúrovňového dědění. Na první úrovni se nachází abstraktní třída SymmetricAlgorithm a specifikuje, že se jedná o symetrický algoritmus. Na následující (druhé) úrovni se nacházejí třídy pojmenované po patřičném typu symetrického algoritmu. Třídy na druhé úrovni jsou rovněž abstraktní. Na poslední (třetí) úrovni se nachází kompletní implementace symetrických algoritmů. Je realizována buď s použitím tzv. poskytovatelů kryptografických služeb ve Windows CryptoAPI (Cryptographic Service Providers) nebo vlastní implementací v .NET.

Symetrické algoritmy v .NET jsou pojmenovány podle toho, zda jsou realizovány s pomocí Windows a jejich poskytovatelem kryptografických služeb nebo mají vlastní implementaci v .NET. Přípona algoritmu označuje jejich způsob realizace.

  • RC2CryptoServiceProvider

  • DESCryptoServiceProvider

  • TrippleDESCryptoServiceProvider

  • RijndaelManaged

Když dojde k vytovření instance konkrétního algoritmu, její konstruktor vytvoří silný tajný klíč a nastaví všechny hodnoty potřebné pro kódování.

Následující příklad načte ze souboru text, který s pomocí symetrického algoritmu DES zakóduje do výstupního souboru DESencrypted.txt.

[ukázka kódu]
using System.Security.Cryptography;
...
   string filename;
   // nactu pole bytu z vytvorenych funkci
   byte[] byteArrayInput = StringToByteArray(GetStringFromFile(filename));

   // DES algoritmus
   DESCryptoServiceProvider des = new DESCryptoServiceProvider();

   // rozhrani pro zakladni operace s kryptografickymi transformacemi
   // vytvoreni koderu
   ICryptoTransform desEncrypt = des.CreateEncryptor();

   // vytvori se kryptovaci stream transformujici soubor s danou krypt. metodou
   CryptoStream cryptostream = new CryptoStream(
   new FileStream("DESencrypted.txt", FileMode.Create, FileAccess.Write), 
      desEncrypt, 
      CryptoStreamMode.Write);

   // zapise se zakodovany soubor
   cryptostream.Write(byteArrayInput, 0, byteArrayInput.Length);
   cryptostream.Close();
...

1.2. Asymetrické kódování

Asymetrické algoritmy nejsou tak rychlé jako symetrické, ale jsou o mnoho bezpečnější. Tyto algoritmy spoléhají na dva klíče - veřejný a soukromý. Veřejný klíč se používá ke kódování zprávy, zatímco soukromý je použit pro dekódování zprávy. Jelikož nejsou rychlé, nejsou asymetrické algoritmy příliš vhodné pro přenos většího množství dat. Jeden klasický příklad použití asymetrického kódování je zakódovat a přenést druhé straně symetrický klíč a inicializační vektor (IV). Pak se přenos provádí s použitím symetrického kódování.

Asymetrické má podobně jako symetrické kódování také tříúrovňovou strukturu dědičnosti. Pokud se vytvoří instance konkrétního asymetrického algoritmu, konstruktor vždy vygeneruje náhodné páry klíčů (silné hodnoty klíčů). Asymetrické algoritmy mohou být také vytvořeny tak, aby mohly získat páry klíčů z kontejneru klíčů Crypto Service Provideru.

Asymetrické algoritmy (názvy tříd) implementované v .NET:

  • RSACryptoServiceProvider

    RSA

  • DSACryptoServiceProvider

    DSA

Následujcí příklad zakóduje vstupní text s použitím algoritmu RSA

[ukázka kódu]
using System.Security.Cryptography;
...
   byte[] rsaByteArray;

   RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
   // do rsaByteArray se ulozi kodovany obsah vstupiho (nekodovaneho) pole typu byte
   rsaByteArray = rsa.Encrypt(byteArrayInput, false);
...

1.3. Hashování

[znalosti]

Hash hodnoty (nazývané také výtažky zpráv, otisky zpráv, obsahy zpráv) se používají všude tam, kde si nepřejeme získat původní hodnotu zprávy. Tedy i nechceme po nikom jiném, aby ji získal.

Hashovací funkce vemou řetězec libovolné délky a transformují jej na bytový řetězec s pevnou délkou. Jelikož je tento způsob kódování jednocestný, používá se například ke kódování hesel, tedy malých množství dat. Heslo, které napíše uživatel, se zpracuje pomocí některé hash funkce a uloží do databáze. Pokud se chce uživatel přihlásit, napíše své heslo, to se opět zpracuje pomocí hash funkce a porovná s hodnotou uloženou v databázi. Tento způsob je výhodný zejména proto, když dojde k neoprávněnému přístupu do databáze - všechna hesla jsou již pomocí hash funkce kódována, tedy je velice obtížné (i když ne úplně nemožné) zjistit původní heslo.

Hashovací funkce rozlišujeme buď s privátním klíčem nebo bez klíče. Pokud používáme hashovací funkci s klíčem, je třeba tento klíč znát i pro ověření hodnoty vzniklé hashovací funkcí s klíčem.

Typy hashovacích funkci (názvy tříd) bez klíče:

  • MD5CodeServiceProvider

  • SHA1CodeServiceProvider

  • SHA1Managed

  • SHA256Managed

  • SHA384Managed

  • SHA512Managed

Typy hashovacích funkcí (názvy tříd) s klíčem:

  • HMACSHA1

    HMAC s použitím algoritmu SHA-1

  • MACTripleDES

    MAC s použitím algoritmu TripleDES

Následující příklad zakóduje řetězec 'krokodýl'

[ukázka kódu]
using System;
using System.Text;
using System.Security.Cryptography;
...
   byte[] byteOutput;
   // hashovaci funkce SHA-1 je ziskana ze tridy SHA1CryptoServiceProvider
   SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
   // prevedeme retezec na pole bytu a vratime ho hashovaci funkci
   byteOutput = sha1.ComputeHash(new ASCIIEncoding.GetBytes("krokodyl"));
   
   // cyklus vytiskne na obrazovku tuto hash hodnotu:
   // 551832f80e3c53545581aa1e833e52bdb177ef
   foreach(byte b in byteOutput) {
      Console.Write("{0:x}", b);
   }
...