Crypto Class

Merhabalar,

Bir yazılım geliştirirken dinamik olarak veya statik olarak saklamak istediğimiz dataların kolayca okunması ve yorumlanması ciddi güvenlik açıklarına sebebiyet verir. Bu aslında temel bazda başta her yazılımcının sonrasında da her kişinin yaşadığı bir sorundur.

İnsanlar zaman içerisinde gizli tutmak istedikleri bilgileri önceleri saklayarak sonraları ise şifreleyerek korumaya çalışmışlardır. Çünkü bir şeyi saklamak şifrelemek kadar güvenli değildir. İlk büyük şifreleme sistemlerinden bahsetmek isterdim ama konu uzar ve anlatılacak o kadar çok şey çıkar ki amacımızdan sapmış oluruz.

En büyük sorun Web tabanlı yazılım geliştirirken verilerimizin kolayca okunup snifflenmemesini sağlamaktır.

Aşağıda paylaşacağım Class ile bu soruna çok ciddi bir boyutta çözüm üretmiş olacaksınız. Peki neden “En büyük sorun Web tabanlı yazılım geliştirme” de? Aslında bunun cevabı çok basit 2 sayfa arası veri taşınması gerekiyorsa veya kullanıcı giriş işlemi yapılması gerekiyorsa veya biraz daha komplike bir örnek vermek gerekirse giriş yapan/yapmayan kullanıcılara bir ürün satmaya çalışıyorsak, o sepetin id bilgisini bir şekilde saklamamız lazım. Bunu da temek olarak 4 farklı yöntemle yapabiliriz;

  • Cookie (Çerez) kullanımı
  • Session (Oturum) kullanımı
  • Browser Database (Tarayıcı Veritabanı)
  • Sepet olmadan direk tek ürün satışı 🙂

Hangi yöntemi kullanırsak kullanalım (Sonuncu yöntem hariç) paylaşacağım Şifreleme Classı ile verilerinizi güvenle saklayabilir ve kullanabilirsiniz.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

public class Crypto
{
    private static byte[] _salt = Encoding.ASCII.GetBytes("o6806642kbM7c5");

    /// <summary>
    /// fatihbas.net Verilen string ifadeyi AES kullanarak şifreler. Şifrelenen metin        
    /// fatihbas.net DecryptStringAES() kullanılarak şifresi çözülebilir. 
    /// 
    /// </summary>
    /// <param name="plainText">şifrelenecek metin</param>
    /// <param name="sharedSecret">şifreleme için kullanılacak parola</param>
    public static string SifreleAES(string plainText, string sharedSecret)
    {
        if (string.IsNullOrEmpty(plainText))
            throw new ArgumentNullException("plainText");
        if (string.IsNullOrEmpty(sharedSecret))
            throw new ArgumentNullException("sharedSecret");

        string outStr = null;
        RijndaelManaged aesAlg = null;

        try
        {

            Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt);
            aesAlg = new RijndaelManaged();
            aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);


            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);


            using (MemoryStream msEncrypt = new MemoryStream())
            {

                msEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof(int));
                msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length);
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(plainText);
                    }
                }
                outStr = Convert.ToBase64String(msEncrypt.ToArray());
            }
        }
        finally
        {

            if (aesAlg != null)
                aesAlg.Clear();
        }


        return outStr;
    }
    /// <summary>
    /// EncryptStringAES() ile şifrelenen metnin şifresini çözer.        
    /// <param name="cipherText">Deşifre edilecek metin fatihbas.net</param>
    /// <param name="sharedSecret">Paylaşılan gizli anahtar</param>
    public static string SifreyiCozAES(string cipherText, string sharedSecret)
    {
        try
        {
            if (string.IsNullOrEmpty(cipherText))
                throw new ArgumentNullException("cipherText");
            if (string.IsNullOrEmpty(sharedSecret))
                throw new ArgumentNullException("sharedSecret");
        }
        catch
        { }


        RijndaelManaged aesAlg = null;


        string plaintext = null;

        try
        {

            Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt);


            byte[] bytes = Convert.FromBase64String(cipherText);
            using (MemoryStream msDecrypt = new MemoryStream(bytes))
            {

                aesAlg = new RijndaelManaged();
                aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
                aesAlg.IV = ReadByteArray(msDecrypt);

                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))

                        //fatihbas.net
                        plaintext = srDecrypt.ReadToEnd();
                }
            }
        }
        finally
        {

            if (aesAlg != null)
                aesAlg.Clear();
        }

        return plaintext;
    }

    private static byte[] ReadByteArray(Stream s)
    {
        byte[] buffer = null;
        try
        {
            byte[] rawLength = new byte[sizeof(int)];
            if (s.Read(rawLength, 0, rawLength.Length) != rawLength.Length)
            {
                throw new SystemException("Stream did not contain properly formatted byte array");
            }

            buffer = new byte[BitConverter.ToInt32(rawLength, 0)];
            if (s.Read(buffer, 0, buffer.Length) != buffer.Length)
            {
                throw new SystemException("Did not read byte array properly");
            }
        }
        catch
        { }
        return buffer;
    }
}

Projemize bir “Class (Sınıf)” ekliyoruz ve içerisine paylaştığım bu kodları direkt olarak yapıştırın.

İşin aslında en zor kısmı burasıydı diyebilirim 🙂

string SifreliVeri = Crypto.SifreleAES("Şifrelenecek String Veri", "Şifreleme Anahtarı");
string SifresiCozulmusVeri = Crypto.SifreyiCozAES(SifreliVeri, "Şifreleme Anahtarı");

Bu kadar kod karmaşası bu kadar aksiyon, 2 satır kod içindi. Unutulmaması gerek tek ve en önemli konu ise datanızı şifreleyecek ve açacak olan “Şifreleme Anahtarı” nın aynı olması gerektiği.

Anlamadığınız veya sormak istediğiniz şeyler olursa yorumlar üzerinden bildirebilirsiniz.

Paylaş :

Bu gönderiyi paylaş

Comments (2)

  • Serhat Bilen cevap

    Çok faydalı bir kaynak

    Aralık 15, 2020 , 10:19 am

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.