İçeriğe geç
Programlama

Python ile MD5 ve SHA-256 Hash Hesaplama (hashlib)

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

Kısaca cevap

Python MD5 hash için standart kütüphanedeki hashlib yeterlidir: hashlib.md5("merhaba".encode("utf-8")).hexdigest(). SHA-256 için md5 yerine sha256 yazın; dosyalar için Python 3.11+ hashlib.file_digest() kullanın. MD5 ve SHA-256 dosya doğrulama içindir, şifre saklamak için uygun değildir. Aşağıdaki kodlar Python 3.14 ile çalıştırıldı.

Bu sayfada

Python MD5 hash string: metnin MD5 ve SHA-256 değeri

Hash (özet) fonksiyonu, herhangi uzunluktaki veriden sabit uzunlukta bir değer üretir. Aynı girdi her zaman aynı özeti verir; girdideki tek bir harf değişse özet tamamen değişir. Python'da bunun için hashlib modülü kullanılır:

import hashlib

metin = "merhaba"
print(hashlib.md5(metin.encode("utf-8")).hexdigest())
print(hashlib.sha256(metin.encode("utf-8")).hexdigest())
c39436ee452e641cde2eb992ab397911
4c6bcdd55f3153e1939669ab1ec039e4059174dc25abdfcb2f58868849b4d61b

Bu değerler her bilgisayarda aynıdır; sonucu sitedeki MD5 ve SHA-256 hash hesaplama aracıyla veya aynı metni C#, Java gibi başka bir dilde özetleyerek karşılaştırabilirsiniz. Hash kavramının kendisini hash nedir yazısında bulabilirsiniz.

Eski örneklerde bu işlem "MD5 şifreleme" diye anlatılır, ama hash bir şifreleme değildir: şifrelenen veri anahtarla geri açılır, özet ise geri çevrilemez.

hexdigest ile digest farkı ve çıktı uzunlukları

digest() ham baytları, hexdigest() ise bu baytların onaltılık (hex) metin karşılığını döndürür. Her bayt iki hex karakter tuttuğu için metin, bayt sayısının iki katı uzunluktadır:

import hashlib

h = hashlib.sha256(b"merhaba")
print(len(h.digest()), h.digest()[:4])
print(len(h.hexdigest()))
32 b'Lk\xcd\xd5'
64
AlgoritmaÖzet (bayt)hexdigest() uzunluğuUygun kullanım
md51632 karakterYalnızca güvenlik dışı sağlama (checksum)
sha12040 karakterEski sistemlerle uyumluluk
sha2563264 karakterDosya doğrulama, bütünlük kontrolü
sha51264128 karakterDosya doğrulama, bütünlük kontrolü

Veritabanında veya bağlantıda kullanacaksanız hexdigest(), başka bir kriptografik işleme girdi olarak vereceksiniz digest() daha uygundur.

Kodlama (encoding) sonucu nasıl değiştirir?

hashlib metin değil bayt ister. hashlib.md5("merhaba") yazarsanız TypeError: Strings must be encoded before hashing hatası alırsınız. Metni bayta çevirirken seçtiğiniz kodlama da önemlidir. Türkçe karakter içeren bir kelime, farklı kodlamalarda farklı baytlara dönüşür ve farklı özet verir:

import hashlib

metin = "şifre"
print(hashlib.md5(metin.encode("utf-8")).hexdigest())
print(hashlib.md5(metin.encode("cp1254")).hexdigest())
905fed16367ac5f65922da066223aeeb
d4dd79d98929717f0907e7057938d6b8

cp1254, eski Windows sistemlerinde kullanılan Türkçe kod sayfasıdır. Başka bir sistemin ürettiği özetle karşılaştırma yapıyorsanız iki tarafın da aynı kodlamayı (çoğunlukla UTF-8) kullandığından emin olun. Eşleşmeyen özetlerin en sık nedeni budur.

Python SHA-256 of file: dosyanın MD5 ve SHA-256 değeri

İndirdiğiniz bir dosyanın yayıncının verdiği özetle aynı olup olmadığını kontrol etmek, hash fonksiyonlarının en yaygın kullanımıdır. Python 3.11 ile gelen hashlib.file_digest bu işi tek satırda yapar:

import hashlib

with open("ornek.txt", "rb") as f:
    ozet = hashlib.file_digest(f, "sha256")
print(ozet.hexdigest())
de208334b2d386b0f38c8f3123c149ace9cba507cbe33a89dd28958efb98ee4f

Dosya ikili ("rb") kipte açılmalıdır. Örnekteki ornek.txt "merhaba" kelimesini ve bir satır sonu içerir; bu yüzden özeti, yukarıdaki "merhaba" metninin özetinden farklıdır. Dosyadaki görünmeyen bir satır sonu bile sonucu değiştirir.

Python MD5 file: eski sürümler için parça parça okuma

Python 3.11'den eski bir sürümde veya birden fazla algoritmayı aynı fonksiyonla hesaplamak istediğinizde dosyayı parçalar hâlinde okuyun. Böylece gigabaytlarca büyüklükteki dosyalar da belleğe tamamen yüklenmez:

import hashlib

def dosya_ozeti(yol, algoritma="md5", parca=1024 * 1024):
    h = hashlib.new(algoritma)
    with open(yol, "rb") as f:
        while blok := f.read(parca):
            h.update(blok)
    return h.hexdigest()

print(dosya_ozeti("ornek.txt"))
print(dosya_ozeti("ornek.txt", "sha256"))
ee71517ae5ffad6dfd4ddcc19af016a8
de208334b2d386b0f38c8f3123c149ace9cba507cbe33a89dd28958efb98ee4f

update() birden fazla kez çağrılabilir; sonuç, tüm parçalar tek seferde verilmiş gibi aynıdır. SHA-256 sonucunu Windows'taki certutil -hashfile ornek.txt SHA256 komutuyla da karşılaştırdık; iki değer aynı çıktı. := işleci Python 3.8 ile gelmiştir.

Yayıncının sitesinde verilen değerle karşılaştırırken iki şeye dikkat edin. Birincisi, bazı araçlar özeti büyük harfle yazar; karşılaştırmadan önce iki değeri de .lower() ile küçük harfe çevirin. İkincisi, yayıncı SHA-256 veriyorsa MD5 yerine onu kontrol edin. Dosya indirme doğrulamasında karşılaştırılan değer gizli olmadığı için burada düz == yeterlidir; süre sabit karşılaştırma yalnızca gizli değerlerde gerekir.

Python hashlib password: MD5 ve SHA-256 şifre için neden uygun değil?

Eski yazılarda MD5'in kullanıcı şifrelerini saklamak için kullanıldığı anlatılırdı. Bugün bu yöntem güvensiz kabul edilir. Python belgeleri de SHA-256 gibi genel amaçlı özetlerin, tuzla birlikte kullanılsa bile şifre özetlemeye uygun olmadığını belirtir. Nedenleri:

  • Çok hızlıdırlar: Sızan bir veritabanındaki özetler, milyarlarca tahminin denenmesiyle kısa sürede eşleştirilebilir.
  • Tuzsuz özet tekrar eder: Aynı şifreyi kullanan iki kişinin özeti aynıdır ve yaygın şifrelerin MD5 değerleri önceden hesaplanmış listelerde bulunur.
  • MD5'in çakışma direnci kırılmıştır: RFC 6151'e göre MD5, dijital imza gibi çakışma direnci gereken yerlerde artık kabul edilemez.

Standart kütüphanedeki doğru araç hashlib.scrypt'tir: her şifre için rastgele bir tuz kullanır ve bilerek bellek ile işlemci harcar. Aşağıdaki ayarlar OWASP Password Storage Cheat Sheet'teki scrypt önerisidir (N=217, r=8, p=1):

import hashlib
import hmac
import os

N, R, P = 2**17, 8, 1          # OWASP'ın önerdiği en düşük scrypt ayarı
MAXMEM = 256 * 1024 * 1024     # 128 MiB'lık işlem için bellek sınırını yükselt

def sifre_ozetle(sifre):
    tuz = os.urandom(16)
    ozet = hashlib.scrypt(sifre.encode("utf-8"), salt=tuz,
                          n=N, r=R, p=P, maxmem=MAXMEM, dklen=32)
    return tuz, ozet

def sifre_dogrula(sifre, tuz, kayitli_ozet):
    ozet = hashlib.scrypt(sifre.encode("utf-8"), salt=tuz,
                          n=N, r=R, p=P, maxmem=MAXMEM, dklen=32)
    return hmac.compare_digest(ozet, kayitli_ozet)

tuz, ozet = sifre_ozetle("Gizli-Parola-2026")
print(sifre_dogrula("Gizli-Parola-2026", tuz, ozet))
print(sifre_dogrula("yanlis-parola", tuz, ozet))
True
False

maxmem değerini yükseltmek gerekir: bu ayarlar yaklaşık 128 MiB bellek kullanır ve OpenSSL'in varsayılan sınırı 32 MiB olduğu için parametre verilmezse ValueError: ... memory limit exceeded hatası alınır (denemede bu hatayı gördük). Tuz gizli değildir; özetle birlikte saklanır. Karşılaştırma için == yerine, süre farkından bilgi sızdırmamak üzere tasarlanmış hmac.compare_digest kullanıldı.

Argon2 veya bcrypt tercih ederseniz argon2-cffi ve bcrypt gibi yaygın paketler bulunur. Örnekler Python ile bcrypt ve Argon2 yazısında, algoritmaların karşılaştırması şifre saklama yazısında.

Anahtarlı özet: hmac 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 kolayca hesaplayabilir. Bir webhook veya API isteğinin gerçekten anahtarı bilen taraftan geldiğini kontrol etmek için HMAC kullanılır. Python'da bunun için standart kütüphanedeki hmac modülü vardır:

import hashlib
import hmac

anahtar = b"gizli-anahtar"
mesaj = "merhaba".encode("utf-8")

imza = hmac.new(anahtar, mesaj, hashlib.sha256).hexdigest()
print(imza)
0aa2ac0fc13599bb2a993f0a26f83365bdf6b2c0004412bb8b0593664e03501b

Aynı anahtar ve mesajla C# (HMACSHA256.HashData) ve Java (Mac.getInstance("HmacSHA256")) da bu değeri verdi. Gelen imzayı kendi hesapladığınızla karşılaştırırken yine hmac.compare_digest(imza, gelen_imza) kullanın. Gerçek uygulamada anahtarı kodun içine yazmayın; ortam değişkeni veya gizli anahtar deposu gibi ayrı bir yerde tutun.

Dikkat edilmesi gerekenler

  • Güvenlik dışı MD5 kullanımını belirtin: Python 3.9'dan beri hashlib.md5(veri, usedforsecurity=False) yazarak özetin güvenlik amacıyla kullanılmadığını belirtebilirsiniz. Belgelere göre MD5, nadir bulunan "FIPS uyumlu" Python derlemelerinde engellenmiş olabilir; bu parametre o ortamlarda kullanıma izin verir.
  • Doğrulamada SHA-256 tercih edin: Yeni bir sistem tasarlıyorsanız dosya doğrulama için bile MD5 yerine SHA-256 kullanın.
  • Kodlamayı sabitleyin: Her yerde encode("utf-8") kullanın.

Aynı işlemlerin diğer dillerdeki karşılıkları: C# ile MD5 ve SHA-256 ve Java ile MD5 ve SHA-256. Kod yazmadan hızlıca bir özet hesaplamak için hash hesaplama aracını kullanabilirsiniz.

Sık sorulan sorular

Python'da MD5 hash nasıl alınır?

hashlib modülünü içe aktarın, metni bayta çevirip md5 fonksiyonuna verin ve hexdigest ile onaltılık metin olarak alın; örneğin hashlib.md5("merhaba".encode("utf-8")).hexdigest(). hashlib standart kütüphanededir, ek paket gerekmez.

hashlib.md5 neden "Strings must be encoded before hashing" hatası veriyor?

hashlib fonksiyonları metin (str) değil bayt ister. Metni önce encode("utf-8") ile bayta çevirin. Kodlamayı her yerde aynı tutun; Türkçe karakter içeren bir metin farklı kodlamalarla farklı özet verir.

Python ile bir dosyanın SHA-256 değeri nasıl hesaplanır?

Python 3.11 ve sonrasında dosyayı "rb" kipinde açıp hashlib.file_digest(dosya, "sha256").hexdigest() çağırın. Daha eski sürümlerde dosyayı parça parça okuyup her parçayı update ile özete ekleyen bir döngü aynı sonucu verir ve büyük dosyaları belleğe yüklemez.

MD5 ile şifre saklamak güvenli mi?

Hayır. MD5 ve SHA-256 çok hızlı çalışır; bu, sızan bir veritabanındaki şifrelerin deneme yanılmayla hızla bulunabilmesi demektir. Python belgeleri de SHA-256 gibi genel amaçlı özetlerin tuzlu olsa bile şifre özetlemeye uygun olmadığını yazar. Bunun yerine scrypt, Argon2 veya bcrypt kullanın.

MD5 çözülebilir mi?

Hash tek yönlüdür; özetten orijinal metin hesaplanamaz. Ancak kısa veya yaygın şifrelerin MD5 değerleri önceden hesaplanıp listelenmiş olduğu için bu tür şifreler listelerde aranarak bulunabilir. Bu da MD5'in şifre saklamak için uygun olmamasının bir nedenidir.