Kategoriler
C# Programlama

Hash Fonksiyonları

Hash fonksiyonları değişken uzunluklu veri kümelerini, sabit uzunluklu verilere dönüştüren fonksiyonlardır.

İdeal bir hash fonksiyonunda aşağıdaki özellikler bulunur:

  • Herhangi bir mesaj için hash değerini hesaplamak kolaydır.
  • Herhangi bir hash değerinden mesajı elde etmek imkânsızdır.
  • Hash değeri değişmeden mesajı değiştirmek imkânsızdır.
  • İki farklı mesajdan aynı hash değerini elde etmek imkânsızdır.
  • Hash fonksiyonlarına gelen data sadece 1 bit bile değişse ortaya çıkan hash tamamen farklıdır.

MD5(message digest)

1991 yılında Ron Rivest tarafından geliştirilmiştir. Aligoritma 128-bit’lik(16-byte) bir sonuç üretir. Aligoritmanın bazı zayıflıkları tespit edilmiş olsa da kırıldığı tam olarak ispatlanamadığı için günümüzde  kullanılmaktadır.

Özellikleri:

  • Tek yönlü çalışır
  • MD5 algoritması ile bir dosyada değişiklik yapılıp yapılmadığını anlayabiliriz.
  • MD4’e göre daha yavaştır ama daha güvenlidir.

MD5 günümüzde SSL, VPN , SSH gibi yerlerde kullanılır. Login olduğumuz çoğu sistemde şifreler açık olarak tutulmaz, şifrenin MD5’li hali tutulur. MD5 tek yönlü olduğu için bu tip sistemler unutulan şifreleri kullanıcıya geri döndüremezler. Sistem random olarak kullanıcıya yeni şifre atar. Ayrıca bu tip sistemlerde iki farklı kullanıcı aynı şifreyi kullandığında aynı hash değerine sahip olacağı için çakışma yaşanır. Çakışmanın önüne geçmek için ise ikincil gerekirse üçüncül sınama yöntemleri uygulanır.

Brute Force Atakları

MD5 algoritması tek yönlü olduğu için geri dönüştürülemiyor demiştik. Bu algoritmaya brute force yapmak için ise bir sözlük oluşturuluyor. Bu sözlük büyük harf, küçük harf, sayılar, özel karakterlerden oluşuyor. Bu sözlükteki kelimeler teker teker MD5 fonksiyonundan geçirilerek bir veri tabanında saklanıyor. Somut bir örnek vermek gerekirse;

Daha önceden yazdığım MD5 fonksiyonuna “erkan” datasını gönderiyorum ve hashli halini alıyorum.

md5

Bu hashi http://md5cracker.org/ sitesinde tarattığımda ise

md5_2

tekrar kendi datama ulaşabiliyorum. Yeni geliştirilen sistemlerde ise şifrelenmiş veriyi birkaç kez daha şifreleyerek bu tip saldırılardaki başarıya ulaşma şansı daha aza indirilmiştir.

Şifrelenmiş veriyi tekrar şifrelediğimde sonuca ulaşılamıyor.

md5_3

 

md5_4

public static string HashMD5(string message)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            byte[] btr = Encoding.UTF8.GetBytes(message);
            btr = md5.ComputeHash(btr);

            StringBuilder sb = new StringBuilder();

            foreach (byte ba in btr)
            {
                sb.Append(ba.ToString("x2").ToLower());
            }
            return sb.ToString();
        }

 

veya aşağıdaki metodu da kullanabilirsiniz.

public class HashDataMD5
    {
        public static byte[] HashMD5(byte[] toBeHash)
        {
            using (var md5 = MD5.Create())
            {
                return md5.ComputeHash(toBeHash);
            }
        }
    }

 

static void Main(string[] args)
        {
            string message1 = "erkan";
            string message2 = "liman";
            Console.WriteLine("MD5 örneği");
            Console.WriteLine("----------------");
            Console.WriteLine();
            Console.WriteLine("Orjinal mesaj1: " + message1);
            Console.WriteLine("Orjinal mesaj2: " + message2);
            Console.WriteLine();

            string hashedMessage1 = HashDataMD5.HashMD5(message1);
            string hashedMessage2 = HashDataMD5.HashMD5(message2);
            Console.WriteLine("Mesaj1 Hash: "+ hashedMessage1);
            Console.WriteLine("Mesaj2 Hash: " + hashedMessage2);
        }

Çıktı:

md5_5

 

Secure Hash Algorithm (SHA)

Güvenli özetleme aligoritması anlamına gelmektedir. NSA (National Security Agency) tarafından tasarlanmıştır. Günümüzde, SHA-0, SHA-1, SHA-2 olmak üzere 3 varyantı vardır. Ayrıca SHA-3 özeteleme algoritmasını daha .NET platformu desteklememektedir. Ancak üçüncü parti implementasyonları bulunmaktadır.

public static byte[] HashSHA1(byte[] toBeHash)
        {
            using (var sha1 = SHA1.Create())
            {
                return sha1.ComputeHash(toBeHash);
            }
        }
public static byte[] HashSHA256(byte[] toBeHash)
        {
            using (var sha1 = SHA256.Create())
            {
                return sha1.ComputeHash(toBeHash);
            }
        }
public static byte[] HashSHA512(byte[] toBeHash)
        {
            using (var sha1 = SHA512.Create())
            {
                return sha1.ComputeHash(toBeHash);
            }
        }
static void Main(string[] args)
        {
            #region testSHAAlgorithm
            string SHAmessage1 = "erkan";
            string SHAmessage2 = "liman";
            Console.WriteLine("SHA örneği");
            Console.WriteLine("----------------");
            Console.WriteLine();
            Console.WriteLine("Orjinal mesaj1: " + SHAmessage1);
            Console.WriteLine("Orjinal mesaj2: " + SHAmessage2);
            Console.WriteLine();

            var sha1HashedMessage1 = 
                SHA.HashSHA1(Encoding.UTF8.GetBytes(SHAmessage1));
            var sha1HashedMessage2 =
                SHA.HashSHA1(Encoding.UTF8.GetBytes(SHAmessage2));


            var sha256HashedMessage1 =
                SHA.HashSHA256(Encoding.UTF8.GetBytes(SHAmessage1));
            var sha256HashedMessage2 =
                SHA.HashSHA256(Encoding.UTF8.GetBytes(SHAmessage2));


            var sha512HashedMessage1 =
                SHA.HashSHA512(Encoding.UTF8.GetBytes(SHAmessage1));
            var sha512HashedMessage2 =
                SHA.HashSHA512(Encoding.UTF8.GetBytes(SHAmessage2));

            Console.WriteLine("SHA1 HASH");
            Console.WriteLine("-------------------");
            Console.WriteLine("Mesaj1 Hash: " + Convert.ToBase64String(sha1HashedMessage1));
            Console.WriteLine("Mesaj2 Hash: " + Convert.ToBase64String(sha1HashedMessage2));
            Console.WriteLine();

            Console.WriteLine("SHA256 HASH");
            Console.WriteLine("-------------------");
            Console.WriteLine("Mesaj1 Hash: " + Convert.ToBase64String(sha256HashedMessage1));
            Console.WriteLine("Mesaj2 Hash: " + Convert.ToBase64String(sha256HashedMessage2));
            Console.WriteLine();

            Console.WriteLine("SHA512 HASH");
            Console.WriteLine("-------------------");
            Console.WriteLine("Mesaj1 Hash: " + Convert.ToBase64String(sha512HashedMessage1));
            Console.WriteLine("Mesaj2 Hash: " + Convert.ToBase64String(sha512HashedMessage2));
            Console.WriteLine();


            #endregion

        }

Çıktı:

sha_1Mesaj Doğrulama Kodu(Message Authentication Code)

Mesaj doğrulama kodları kriptolojide mesajın doğruluğunu kanıtlamak için kullanılır. Bu algoritma parametre olarak gizli anahtar ve karşıya iletilecek(doğruluğu ispatlanacak) mesajı alır. Çıktı olarak mesaj doğrulama kodu verir. Bu sayede alıcı mesajda değişiklik olup olmadığını anlayabilir. Bu işlem için daha önce yazdığım kriptografik rastgele sayı üreteçlerine göz atmanızı tavsiye ederim.

public class MDK
    {
        private const int SIZE = 32;

        public static byte[] GenerateKey()
        {
            using (var randomNumber = new RNGCryptoServiceProvider())
            {
                var randomNumbers = new byte[SIZE];
                randomNumber.GetBytes(randomNumbers);
                return randomNumbers;
            }
        }

        public static byte[] MDKSHA256(byte[] toBeHash, byte[] key)
        {
            using (var mdk = new HMACSHA256(key))
            {
                return mdk.ComputeHash(toBeHash);
            }
        }

        public static byte[] MDKSHA1(byte[] toBeHash, byte[] key)
        {
            using (var mdk = new HMACSHA1(key))
            {
                return mdk.ComputeHash(toBeHash);
            }
        }

        public static byte[] MDKSHA512(byte[] toBeHash, byte[] key)
        {
            using (var mdk = new HMACSHA512(key))
            {
                return mdk.ComputeHash(toBeHash);
            }
        }

        public static byte[] MDKMD5(byte[] toBeHash, byte[] key)
        {
            using (var mdk = new HMACMD5(key))
            {
                return mdk.ComputeHash(toBeHash);
            }
        }

    }

 

static void Main(string[] args)
        {
            
            #region mdkTest
            string MDKmessage1 = "erkan";
            string MDKmessage2 = "liman";
            Console.WriteLine("Mesaj Doğrulama kodu örneği");
            Console.WriteLine("-------------------------------");
            Console.WriteLine();
            Console.WriteLine("Orjinal mesaj1: " + MDKmessage1);
            Console.WriteLine("Orjinal mesaj2: " + MDKmessage2);
            Console.WriteLine();

            var key = MDK.GenerateKey();


            var mdkMD5Message1 =
                MDK.MDKMD5(Encoding.UTF8.GetBytes(MDKmessage1), key);
            var mdkMD5Message2 =
                MDK.MDKMD5(Encoding.UTF8.GetBytes(MDKmessage2), key);


            var mdkSHA512Message1 =
                MDK.MDKSHA512(Encoding.UTF8.GetBytes(MDKmessage1), key);
            var mdkSHA512Message2 =
                MDK.MDKSHA512(Encoding.UTF8.GetBytes(MDKmessage2), key);


            var mdkSHA256Message1 =
                MDK.MDKSHA256(Encoding.UTF8.GetBytes(MDKmessage1), key);
            var mdkSHA256Message2 =
                MDK.MDKSHA256(Encoding.UTF8.GetBytes(MDKmessage2), key);


            var mdkSHA1Message1 =
                MDK.MDKSHA1(Encoding.UTF8.GetBytes(MDKmessage1), key);
            var mdkSHA1Message2 =
                MDK.MDKSHA1(Encoding.UTF8.GetBytes(MDKmessage2), key);


            Console.WriteLine("MD5 Mesaj Doğrulama Kodu");
            Console.WriteLine("----------------------------");
            Console.WriteLine("Key: " + Convert.ToBase64String(key));
            Console.WriteLine("Mesaj 1 hash : " + Convert.ToBase64String(mdkMD5Message1));
            Console.WriteLine("Mesaj 2 hash : " + Convert.ToBase64String(mdkMD5Message2));


            Console.WriteLine("SHA512 Mesaj Doğrulama Kodu");
            Console.WriteLine("----------------------------");
            Console.WriteLine("Key: " + Convert.ToBase64String(key));
            Console.WriteLine("Mesaj 1 hash : " + Convert.ToBase64String(mdkSHA512Message1));
            Console.WriteLine("Mesaj 2 hash : " + Convert.ToBase64String(mdkSHA512Message2));

            Console.WriteLine("SHA256 Mesaj Doğrulama Kodu");
            Console.WriteLine("----------------------------");
            Console.WriteLine("Key: " + Convert.ToBase64String(key));
            Console.WriteLine("Mesaj 1 hash : " + Convert.ToBase64String(mdkSHA256Message1));
            Console.WriteLine("Mesaj 2 hash : " + Convert.ToBase64String(mdkSHA256Message2));

            Console.WriteLine("SHA1 Mesaj Doğrulama Kodu");
            Console.WriteLine("----------------------------");
            Console.WriteLine("Key: " + Convert.ToBase64String(key));
            Console.WriteLine("Mesaj 1 hash : " + Convert.ToBase64String(mdkSHA1Message1));
            Console.WriteLine("Mesaj 2 hash : " + Convert.ToBase64String(mdkSHA1Message1));

            #endregion

        }

 

Çıktı:

mdk_1

Projeyi buradan indirebilirsiniz.

Kaynaklar:

https://en.wikipedia.org/wiki/Hash_function

https://tr.wikipedia.org/wiki/Mesaj_Do%C4%9Frulama_Kodu

 

 

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

This site uses Akismet to reduce spam. Learn how your comment data is processed.