1. Szyfrowanie symetryczne
Szyfrowanie symetryczne opiera się na jednym kluczu użytym zarówno do szyfrowania jak i deszyfrowania danych. Obecnie zalecane jest używanie algorytmu Rijndael - dokładny opis można znaleźć w wikipedii:
http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
Code:
class Program
{
static void Main(string[] args)
{
using (var rm = new RijndaelManaged())
{
byte[] encrypted = EncryptRijndaelManaged("Ala ma kota", rm.Key, rm.IV);
string decrypted = DecryptRijndaelManaged(encrypted, rm.Key, rm.IV);
Console.WriteLine(decrypted);
}
}
public static byte[] EncryptRijndaelManaged(string input, byte[] key, byte[] IV)
{
byte[] encrypted;
using (var rm = new RijndaelManaged())
{
rm.Key = key;
rm.IV = IV;
ICryptoTransform encryptor = rm.CreateEncryptor(rm.Key, rm.IV);
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
using (var swEncrypt = new StreamWriter(cs))
{
swEncrypt.Write(input);
}
encrypted = ms.ToArray();
}
}
}
return encrypted;
}
public static string DecryptRijndaelManaged(byte[] input, byte[] key, byte[] IV)
{
string decrypted;
using (var rm = new RijndaelManaged())
{
rm.Key = key;
rm.IV = IV;
ICryptoTransform decryptor = rm.CreateDecryptor(rm.Key, rm.IV);
using (var ms = new MemoryStream(input))
{
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (var swDecrypt = new StreamReader(cs))
{
decrypted = swDecrypt.ReadToEnd();
}
}
}
}
return decrypted;
}
}
2. Szyfrowanie asymetryczne
Jest to dużo bardziej bezpieczne rozwiązanie. Tworzone są dwa klucze:
- prywatny - trzymany na serwerze w bezpiecznym i niedostępnym miejscy
- publiczny - wysyłany do zainteresowanych
Szyfrowanie odbywa się za pomocą jednego z tych kluczy, a odszyfrowanie za pomocą drugiego. Jednym z najpopularniejszych algorytmów asymetrycznych jest RSA. Przykład szyfrowania i deszyfrowania:
Code:
public static byte[] EncryptRsa(string input)
{
const int rsa = 1;
var cspParameters = new CspParameters(rsa);
cspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
cspParameters.KeyContainerName = "My Keys";
var rsaCryptoServiceProvider = new RSACryptoServiceProvider(cspParameters);
byte[] encrypted = rsaCryptoServiceProvider.Encrypt(new UnicodeEncoding().GetBytes(input), true);
return encrypted;
}
public static string DecryptRsa(byte[] input)
{
const int rsa = 1;
var cspParameters = new CspParameters(rsa);
cspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
cspParameters.KeyContainerName = "My Keys";
var rsaCryptoServiceProvider = new RSACryptoServiceProvider(cspParameters);
var decrypted = rsaCryptoServiceProvider.Decrypt(input, true);
return new UnicodeEncoding().GetString(decrypted);
}
3. Hashowanie
Hashowanie jest procesem jednokierunkowym, to znaczy hashujemy podany ciąg znaków zmieniając je w kod, jednak w drugą stronę nie jesteśmy już w stanie (w prosty sposób) odczytać stworzonego hasha.
Istnieje jednak ryzyko, że hashując np. hasło w bazie pojawią się dwa podobne wpisy. Rozwiązaniem tego problemu jest dodanie tzw. soli (Salt) którą dodaje się np. do hasła i taki ciąg znaków dopiero zostaje hashowany. Dzięki takiemu rozwiązaniu mamy znikome prawdopodobieństwo powtórzenia się hashy.
Obecnie zalecane jest stosowane algorytmu SHA256. Przykład użycia algorytmu:
Code:
public static string Sha256Encryption(string input, string salt)
{
byte[] data = new UnicodeEncoding().GetBytes(input + salt);
var sha256Managed = new SHA256Managed();
var computeHash = sha256Managed.ComputeHash(data);
return ToHex(computeHash);
}
private static string ToHex(byte[] computeHash)
{
var hex = new StringBuilder();
foreach (var b in computeHash)
{
hex.AppendFormat("{0:x2}", b);
}
return hex.ToString();
}
4. Cyfrowy podpis
Cyfrowy podpis gwarantuje, że wiadomość została niezmieniona i wysłana przez daną instytucję.
Przykład implementacji:
Code:
public static byte[] CreateSignature(string input)
{
const int rsa = 24;
var cspParameters = new CspParameters(24);
cspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
cspParameters.KeyContainerName = "My Keys";
var rsaCryptoServiceProvider = new RSACryptoServiceProvider(cspParameters);
return rsaCryptoServiceProvider.SignData(new UnicodeEncoding().GetBytes(input), "SHA256");
}
public static bool CheckSign(string input, byte[] signature)
{
const int rsa = 24;
var cspParameters = new CspParameters();
cspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
cspParameters.KeyContainerName = "My Keys";
var rsaCryptoServiceProvider = new RSACryptoServiceProvider(cspParameters);
return rsaCryptoServiceProvider.VerifyData(new UnicodeEncoding().GetBytes(input), "SHA256", signature);
}
return rsaCryptoServiceProvider.SignData(new UnicodeEncoding().GetBytes(input), "SHA256");
OdpowiedzUsuńto zwraca 128 bajtów a nie 256 :(
więc chyba coś nie tak ...