C# - String titkosítása, visszafejtése

forráskód letöltése
A .NET Framework-ben számtalan titkosítási algoritmust találunk, melyhez számos osztály tartozik. Ezeket felhasználva könnyen titkosíthatunk állományokat, stream-eket, viszont nem találunk olyan függvényt, mely egy egyszerű sztringet titkosítana és az eredményt szintén sztringként adná vissza.
Készítünk tehát két függvényt, melyek unicode típusú sztringek titkosítására, visszafejtésére alkalmas. Az egyik Encrypt néven, a másik Decrypt néven kerül létrehozásra. Az Encrypt titkosítja a paraméterként átadott sztringet, míg a Decrypt visszafejti azt. A titkosításhoz a TripleDES nevű algoritmust használjuk fel, melyhez a TripleDESCryptoServiceProvider osztályra lesz szükségünk.
private static TripleDESCryptoServiceProvider csp;
Az osztályunk konstruktorában hozzuk létre ezt az osztályt, és adjuk meg a kódoláshoz, dekódoláshoz szükséges kulcsokat. A key, illetve az iv tömbben megadott értékek ránk vannak bízva, ezek tetszőlegesek lehetnek. A szöveg visszafejtéséhez ezekre az értékekre van szükség.
    static Util()
    {
      csp = new TripleDESCryptoServiceProvider();
      byte[] key = {2, 55, 86, 23, 2, 21, 111, 132, 222, 182, 72, 132, 12, 3, 231, 12};
      byte[] iv = {12, 231, 34, 242, 52, 12, 8, 21};
      csp.Key = key;
      csp.IV = iv;
    }
Nézzük, hogy miként történik a paraméterként kapott sztring titkosítása. Létrehozunk egy memória stream-et, valamint egy ICryptoTransform interfészt.
    public static string Encrypt(string s)
    {
      MemoryStream ms = new MemoryStream();
      ICryptoTransform ct = csp.CreateEncryptor();
Szükségünk lesz egy titkosító stream-re is, melyet a CryptoStream osztály valósít meg. Ennek első paraméterébe a már létrejött memória stream-et adjuk meg, másodikként az ICryptoTransform interfészt. Végső paraméterként azt határozzuk meg, hogy írható legyen ez az adatfolyam.
      CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
Kell még egy StreamWriter osztály, mellyel a titkosítandó sztringet tudjuk majd a memória stream-re írni.
      StreamWriter sw = new StreamWriter(cs, System.Text.Encoding.Unicode);
      sw.Write(s);
      sw.Flush();
      cs.FlushFinalBlock();
Miután ezt megtörtént az adat már titkosítva van a stream-en, most már csak sztringgé kell alakítanunk. Ehhez létrehozunk egy bájtokat tartalmazó tömböt, majd a memória stream-ről kiolvassuk ide az adatokat.
      ms.Position = 0;
      byte[] buf = new byte[ms.Length];
      ms.Read(buf, 0, (int)ms.Length);      
Zárunk minden megnyitott stream-et.
      sw.Close();
      cs.Close();
      ms.Close();
Végül az eredmény buffert Base64 kódolású sztringként adjuk vissza, hogy az könnyen kezelhető, tárolható legyen.
      return Convert.ToBase64String(buf);
    }
Az Encrypt függvény által adott titkosított sztringet kell paraméterként megadnunk a Decrypt függvénynek. Ez végzi el a visszafejtést. Először is egy bájtokat tartalmazó tömböt hozunk létre a Base64 kódolású sztringből.
    public static string Decrypt(string s)
    {       
      byte[] buf = Convert.FromBase64String(s);
Következik a memória stream és az ICryptoTransform interfész létrehozása mint az előbb.
      MemoryStream ms = new MemoryStream();
      ICryptoTransform ct = csp.CreateDecryptor();
A titkosítást végző stream felhasználásával a bájt tömböt a stream-re írjuk és ezzel elvégezzük a visszafejtést.
      CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
      cs.Write(buf, 0, buf.Length);
      cs.FlushFinalBlock();
Az eredmény kiolvasásához egy StreamReader osztályt használunk fel, melynek ReadToEnd függvényét alkalmazva egy lépésben megkapjuk a visszafejtett sztringet.
      ms.Position = 0;
      StreamReader sr = new StreamReader(ms, System.Text.Encoding.Unicode);
      string result = sr.ReadToEnd();
Végül már csak zárni kell a stream-eket és visszaadni az eredmény sztringet.
      cs.Close();
      ms.Close();
      return result;      
    }
A két függvény felhasználása már lényegesen egyszerűbb, mint azok elkészítése. Titkosításhoz egyszerűen meghívjuk az Encrypt függvényt, átadva számára a tikosítandó szöveget.
    private void button1_Click(object sender, System.EventArgs e)
    {
      label1.Text = Util.Encrypt(textBox1.Text);
    }
A titkosított sztringet visszafejthetjük a Decrypt függvény hívásával.
    private void button2_Click(object sender, System.EventArgs e)
    {
      label2.Text = Util.Decrypt(Util.Encrypt(textBox1.Text));    
    }