İçeriğe geç
Programlama

C# ile MD5 ve SHA-256 Hash Hesaplama

Güncellendi: Son kontrol: Eylül 2026 5 dk okuma

Kısaca cevap

C# SHA256 hash için .NET 5 ve sonrasında tek satır yeterlidir: SHA256.HashData(Encoding.UTF8.GetBytes(metin)). MD5 için MD5.HashData aynı biçimde çalışır; sonucu Convert.ToHexStringLower (.NET 9+) ile hex metne çevirirsiniz. MD5 ve SHA-256 veri doğrulama içindir; kullanıcı şifrelerini saklamak için tuzlu PBKDF2 gibi yavaş bir yöntem gerekir. Kodlar .NET 10 ile çalıştırıldı.

Bu sayfada

C# MD5 ve SHA256 hash string: metnin özeti

Hash (özet) fonksiyonu, herhangi uzunluktaki veriden sabit uzunlukta bir değer üretir. Aynı girdi her zaman aynı özeti verir ve özetten orijinal veri geri hesaplanamaz. .NET'te gerekli sınıflar System.Security.Cryptography ad alanındadır:

using System.Security.Cryptography;
using System.Text;

string metin = "merhaba";
byte[] veri = Encoding.UTF8.GetBytes(metin);

string md5 = Convert.ToHexStringLower(MD5.HashData(veri));
string sha256 = Convert.ToHexStringLower(SHA256.HashData(veri));

Console.WriteLine($"MD5    : {md5}");
Console.WriteLine($"SHA-256: {sha256}");
MD5    : c39436ee452e641cde2eb992ab397911
SHA-256: 4c6bcdd55f3153e1939669ab1ec039e4059174dc25abdfcb2f58868849b4d61b

Bu değerler her platformda aynıdır; aynı metni Python ve Java ile özetlediğimizde de bu sonuçları aldık. Sonucu sitedeki MD5 ve SHA-256 hash hesaplama aracıyla da karşılaştırabilirsiniz. MD5 16 bayt (32 hex karakter), SHA-256 32 bayt (64 hex karakter) üretir.

C# MD5 hash string: Encoding.UTF8 mi, Encoding.Unicode mu?

C#'ta en sık yapılan hatalardan biri metni Encoding.Unicode ile bayta çevirmektir. Bu ad yanıltıcıdır: Encoding.Unicode UTF-16 kullanır ve her harf için iki bayt üretir. Sonuç, diğer dillerin ve araçların varsayılan olarak kullandığı UTF-8 özetinden farklı çıkar:

using System.Security.Cryptography;
using System.Text;

string metin = "merhaba";
Console.WriteLine(Convert.ToHexStringLower(MD5.HashData(Encoding.UTF8.GetBytes(metin))));
Console.WriteLine(Convert.ToHexStringLower(MD5.HashData(Encoding.Unicode.GetBytes(metin))));
c39436ee452e641cde2eb992ab397911
cbc2e3430e8d9b5808791586592f7b45

İkinci değer yanlış değildir, ama UTF-16 baytlarının özetidir; bir web servisi veya PHP, Python gibi başka bir dilin ürettiği değerle karşılaştırırsanız eşleşmez. Özel bir gereksinim yoksa her zaman Encoding.UTF8 kullanın.

.NET 5–8 için hex string'e çevirme

Convert.ToHexStringLower .NET 9 ile geldi. Daha eski sürümlerde .NET 5'ten beri bulunan Convert.ToHexString kullanılır; bu metot büyük harf döndürür:

using System.Security.Cryptography;
using System.Text;

byte[] ozet = SHA256.HashData(Encoding.UTF8.GetBytes("merhaba"));
Console.WriteLine(Convert.ToHexString(ozet));                    // BÜYÜK harf
Console.WriteLine(Convert.ToHexString(ozet).ToLowerInvariant()); // .NET 5–8 için küçük harf
4C6BCDD55F3153E1939669AB1EC039E4059174DC25ABDFCB2F58868849B4D61B
4c6bcdd55f3153e1939669ab1ec039e4059174dc25abdfcb2f58868849b4d61b

Büyük ve küçük harfli yazım aynı değeri gösterir. Veritabanında veya başka bir sistemle karşılaştırırken tek bir biçim seçin; aksi hâlde aynı özetler metin olarak "farklı" görünür.

Eski yöntem: Create ve ComputeHash

İnternetteki çoğu örnek (bu sayfanın eski sürümü dahil) nesne oluşturup baytları tek tek "x2" biçimiyle birleştirir. Bu yöntem hâlâ çalışır ve .NET Framework'te tek seçenektir:

using System.Security.Cryptography;
using System.Text;

Console.WriteLine(Sha256Eski("merhaba"));

static string Sha256Eski(string metin)
{
    using SHA256 sha = SHA256.Create();
    byte[] ozet = sha.ComputeHash(Encoding.UTF8.GetBytes(metin));
    var sb = new StringBuilder(ozet.Length * 2);
    foreach (byte b in ozet)
        sb.Append(b.ToString("x2"));
    return sb.ToString();
}
4c6bcdd55f3153e1939669ab1ec039e4059174dc25abdfcb2f58868849b4d61b

Sonuç, yeni yöntemle birebir aynıdır. .NET 5 ve sonrasında HashData daha kısadır ve nesne oluşturup atmanıza gerek bırakmaz. MD5 için de aynı kalıp geçerlidir: MD5.Create() ve ComputeHash.

C# MD5 hash file: dosyanın MD5 ve SHA-256 değeri

İndirilen bir dosyanın yayıncının verdiği özetle aynı olup olmadığını kontrol etmek için dosyayı akış (stream) olarak özetleyin. HashData(Stream) .NET 7 ile geldi ve dosyayı belleğe tamamen yüklemeden okur:

using System.Security.Cryptography;

using FileStream dosya = File.OpenRead("ornek.txt");
byte[] md5 = MD5.HashData(dosya);

dosya.Position = 0; // aynı akışı ikinci kez okumak için başa sar
byte[] sha256 = SHA256.HashData(dosya);

Console.WriteLine(Convert.ToHexStringLower(md5));
Console.WriteLine(Convert.ToHexStringLower(sha256));
ee71517ae5ffad6dfd4ddcc19af016a8
de208334b2d386b0f38c8f3123c149ace9cba507cbe33a89dd28958efb98ee4f

Örnekteki ornek.txt "merhaba" kelimesi ve bir satır sonu içerir; bu yüzden sonuç, yukarıdaki metin özetinden farklıdır. Görünmeyen bir satır sonu bile özeti değiştirir. Aynı dosyayı PowerShell'deki Get-FileHash ornek.txt -Algorithm MD5 komutuyla da özetledik; sonuç büyük harfle yazılmış aynı değerdi.

Web uygulamasında yüklenen dosyaları özetliyorsanız iş parçacığını bekletmemek için .NET 7 ile gelen await SHA256.HashDataAsync(akis) sürümünü kullanabilirsiniz; sonuç aynıdır. Yayıncının verdiği değerle karşılaştırırken büyük-küçük harf farkını gözetmeyin: string.Equals(a, b, StringComparison.OrdinalIgnoreCase).

SHA256 encryption C#: hash şifreleme değildir

"SHA256 şifreleme" ifadesi yaygındır ama tam doğru değildir. Şifreleme (ör. AES) veriyi bir anahtarla gizler ve aynı anahtarla geri açar. Hash ise tek yönlüdür; özetten veri geri elde edilemez. Kullanım yerleri de farklıdır:

AmaçDoğru araç
Dosya bütünlüğü, indirme doğrulamaSHA-256 (SHA256.HashData)
Eski sistemlerle uyumlu sağlama değeriMD5 (yalnızca güvenlik dışı işlerde)
Kullanıcı şifresini saklamaPBKDF2, Argon2, bcrypt veya scrypt
Veriyi gizleyip geri okumaAES gibi simetrik şifreleme

MD5'in çakışma direnci kırılmıştır; RFC 6151 onun dijital imza gibi çakışma direnci gereken yerlerde artık kabul edilemeyeceğini belirtir. Yeni sistemlerde dosya doğrulama için bile SHA-256 tercih edin. Algoritmaların farkını hash nedir yazısında bulabilirsiniz.

C# SHA256 hash with salt example: şifreler nasıl saklanmalı?

Şifreyi tuz (salt) ekleyip SHA-256 ile özetlemek, aynı şifrelerin aynı özeti vermesini önler ama yeterli değildir: SHA-256 çok hızlıdır ve sızan özetler saniyede milyarlarca tahminle denenebilir. Şifre için bilerek yavaş çalışan bir türetme fonksiyonu gerekir. .NET'te yerleşik seçenek Rfc2898DeriveBytes.Pbkdf2'dir (.NET 6+). OWASP Password Storage Cheat Sheet, PBKDF2-HMAC-SHA256 için 600.000 iterasyon önerir:

using System.Security.Cryptography;

const int Iterasyon = 600_000;  // OWASP: PBKDF2-HMAC-SHA256 için önerilen değer
const int TuzBoyu = 16;         // 128 bit
const int OzetBoyu = 32;        // 256 bit

string kayit = SifreOzetle("Gizli-Parola-2026");
Console.WriteLine(kayit);
Console.WriteLine(SifreDogrula("Gizli-Parola-2026", kayit));
Console.WriteLine(SifreDogrula("yanlis-parola", kayit));

static string SifreOzetle(string sifre)
{
    byte[] tuz = RandomNumberGenerator.GetBytes(TuzBoyu);
    byte[] ozet = Rfc2898DeriveBytes.Pbkdf2(
        sifre, tuz, Iterasyon, HashAlgorithmName.SHA256, OzetBoyu);
    return $"{Iterasyon}.{Convert.ToBase64String(tuz)}.{Convert.ToBase64String(ozet)}";
}

static bool SifreDogrula(string sifre, string kayit)
{
    string[] parca = kayit.Split('.');
    int iterasyon = int.Parse(parca[0]);
    byte[] tuz = Convert.FromBase64String(parca[1]);
    byte[] beklenen = Convert.FromBase64String(parca[2]);

    byte[] ozet = Rfc2898DeriveBytes.Pbkdf2(
        sifre, tuz, iterasyon, HashAlgorithmName.SHA256, beklenen.Length);
    return CryptographicOperations.FixedTimeEquals(ozet, beklenen);
}

Örnek çıktı (tuz rastgele olduğu için ilk satır her çalıştırmada farklı olur):

600000.1TfOUzrt7BQZX5yo/AA46g==.w+oRtNlYSf8b1FIEIvBFUoCbECubeelMSDcpX7udzEs=
True
False

Kayıtta iterasyon sayısı, tuz ve özet birlikte tutulur; böylece ileride iterasyonu artırdığınızda eski kayıtlar da doğrulanabilir. Tuz gizli değildir ama her kullanıcı için RandomNumberGenerator ile ayrı üretilmelidir. Karşılaştırmada == yerine, süre farkından bilgi sızdırmayan CryptographicOperations.FixedTimeEquals kullanıldı. Pbkdf2'nin string alan sürümü şifreyi UTF-8 ile bayta çevirir.

OWASP, mümkünse Argon2id'yi, o yoksa scrypt'i öncelikli önerir; PBKDF2 ise .NET'te ek paket gerektirmeyen seçenektir. Argon2 ve bcrypt için ayrı kütüphaneler bulunur. Ayrıntılar C# ile güvenli şifre hashleme ve şifre saklama yazılarında.

HMACSHA256: anahtarlı özet ile mesaj doğrulama

Düz bir özet, verinin bozulup bozulmadığını gösterir ama kimin ürettiğini kanıtlamaz; veriyi değiştiren biri yeni özeti de hesaplayabilir. Webhook veya API isteklerinde mesajın gerçekten anahtarı bilen taraftan geldiğini doğrulamak için HMAC kullanılır. .NET 6 ve sonrasında tek satırlık HMACSHA256.HashData metodu bulunur:

using System.Security.Cryptography;
using System.Text;

byte[] anahtar = Encoding.UTF8.GetBytes("gizli-anahtar");
byte[] mesaj = Encoding.UTF8.GetBytes("merhaba");

byte[] imza = HMACSHA256.HashData(anahtar, mesaj);
Console.WriteLine(Convert.ToHexStringLower(imza));
0aa2ac0fc13599bb2a993f0a26f83365bdf6b2c0004412bb8b0593664e03501b

Aynı anahtar ve mesajla Python'un hmac modülü ve Java'nın Mac sınıfı da bu değeri verdi. Gelen imzayı kendi hesapladığınızla karşılaştırırken yine CryptographicOperations.FixedTimeEquals kullanın ve anahtarı kaynak koda değil, yapılandırma ya da gizli anahtar deposuna koyun.

Dikkat edilmesi gerekenler

  • Kodlamayı sabitleyin: Her yerde Encoding.UTF8 kullanın; Türkçe karakterli metinler farklı kodlamalarda farklı özet verir.
  • Tarayıcıda MD5 yok: Microsoft belgelerine göre MD5.HashData tarayıcı (Blazor WebAssembly) platformunda desteklenmez; orada SHA-256 kullanın.
  • Büyük harf mi küçük harf mi: Karşılaştırmadan önce iki değeri aynı biçime getirin veya baytları doğrudan karşılaştırın.

Aynı işlemlerin diğer dillerdeki karşılıkları: Python ile MD5 ve SHA-256 ve Java ile MD5 ve SHA-256. Güvenli rastgele tuz ve şifre üretimi için C# ile güvenli şifre üretme yazısına bakabilirsiniz.

Sık sorulan sorular

C# ile bir string'in SHA256 hash değeri nasıl alınır?

Metni Encoding.UTF8.GetBytes ile bayta çevirin, SHA256.HashData ile özetleyin ve Convert.ToHexStringLower ile küçük harfli hex metne dönüştürün. SHA256.HashData .NET 5, ToHexStringLower .NET 9 ile geldi; .NET 5–8 arasında Convert.ToHexString(...).ToLowerInvariant() kullanabilirsiniz.

SHA256 bir şifreleme yöntemi mi?

Hayır. SHA-256 bir hash (özet) fonksiyonudur; sonuç anahtarla geri açılamaz. Veriyi gizleyip sonra geri okumanız gerekiyorsa AES gibi bir şifreleme algoritması, veri bütünlüğünü kontrol etmek istiyorsanız hash kullanılır.

C# ile bir dosyanın MD5 değeri nasıl hesaplanır?

Dosyayı File.OpenRead ile açıp akışı MD5.HashData(stream) metoduna verin. Stream alan bu sürüm .NET 7 ile geldi ve dosyayı belleğe tamamen yüklemeden okur. Eski sürümlerde MD5.Create() ile oluşturulan nesnenin ComputeHash(stream) metodu aynı işi yapar.

Şifreleri SHA256 ile tuzlayarak saklamak yeterli mi?

Yeterli değildir. Tuz aynı şifrelerin aynı özeti vermesini önler ama SHA-256 çok hızlı olduğu için sızan özetler hızla denenebilir. Şifreler için bilerek yavaş çalışan bir yöntem gerekir; .NET'te yerleşik seçenek Rfc2898DeriveBytes.Pbkdf2'dir. OWASP, PBKDF2-HMAC-SHA256 için 600.000 iterasyon önerir.

C# MD5 çıktısı neden başka bir araçtan farklı çıkıyor?

En sık nedenler metnin farklı kodlamayla bayta çevrilmesi, metnin sonunda görünmeyen bir boşluk veya satır sonu bulunması ve harf büyüklüğüdür. Convert.ToHexString büyük harf, çoğu araç küçük harf verir; değer aynıdır ama metin karşılaştırmasında farklı görünür.