Güvenli MD5 Kullanımı
26 Ağustos 2006 tarihli, Güvenlik köşesine ait yazı.
MD5 genelde internetten indirdiğimiz dosyaların tam ve doğru olduğunu kontrol ederken veya veritabanında şifreleri saklarken karşımıza çıkan popüler bir tek yönlü şifreleme algoritmasıdır. Ancak tek yönlü olması, şifre gibi bilgilerinizin güvenli saklandığı anlamına gelmiyor. Özellikle uygulamalarında MD5 kullanarak şifreleri saklayanlar ve MD5 şifrelerinin nasıl kırıldığını merak edenler için faydalı bir yazı olduğu düşünüyorum.
MD5 Algoritması Nedir?
MD5 (Message-Digest algorithm 5) aslında bir ÅŸifreleme yöntemi deÄŸil, bir hash function‘dır. Yani herhangi bir uzunlukta verilen mesajı (veya dosyayı) alıp fazla uzun olmayan bir harf ve sayı dizisine çevirir. Siz 700mb büyüklüğünde bir Linux dağıtımının .iso dosyasını indirseniz de, “merhaba, nasılsın?” mesajı yazsanız da, hepsinin MD5 sonucu 128bit uzunluÄŸundadır. 128bit ise 128/4 = 32 hexadecimal sayıyla ifade edilebilir.
Hemen bir örnek verelim: ulusal dağıtımımız olan Pardus’un .iso dosyasını bu klasörde görüyorsunuz. Bakalım bu klasördeki pardus-1.0.iso.md5sum dosyasında ne yazıyor:
Buradaki 32 tane hexadecimal sayı (0-f arası karakterler) pardus-1.0.iso dosyasının MD5 sonucunu gösteriyor. EÄŸer siz bu 700mb’lık dosyayı bilgisayarınıza indirirken 1 bit’lik bile hata yapmış olsaydınız MD5 sonucu çok farklı bir sayı çıkardı! Wikipedia örneÄŸinde cümlede tek harf deÄŸiÅŸince MD5 sonucu da alakasız biçimde deÄŸiÅŸiyor:
= 9e107d9d372bb6826bd81d3542a419d6
MD5(”The quick brown fox jumps over the lazy cog“)
= 1055d3e698d289f2af8663725127bd4b
Tek Yönlü Şifreleme Algoritmaları
Bir algoritmanın tek yönlü şifreleme algoritması olarak kabul edilebilmesi için tabii ki şifrelenmemiş veriye kolayca ulaşmamamız gerekli. Çift yönlü şifreleme algoritmaları encrypt ve decrypt fonksiyonları yardımıyla bir mesajı şifreler ve şifresini çözerler. Ancak, örnek olarak MD5 için bir decryption function yazmak mümkün değildir.
128 bit’lik c84f093c22580a70813dff7d0e9c85bf MD5 hash’ini kullanarak pardus-1.0.iso dosyasını oluÅŸturmamız mümkün deÄŸildir. Ancak MD5 kullanılarak kaydedilmiÅŸ ÅŸifreleri bulmak için uygulanabilecek bazı yöntemler mevcut.
MD5′e Brute Force Saldırılar
Brute Force saldırılar kabaca, tüm olasılıkları deneyerek şifreyi çözmek olarak anlatılabilir. Örnek olarak elinizde c84f093c22580a70813dff7d0e9c85bf MD5 sonucu var, ve siz bunun 6 basamaklı bir sayının MD5 sonucu olduğunu tahmin ediyorsunuz. Yapılacak işlem basit: 6 basamaklı tüm sayıların MD5 sonucuyla elimizdeki sonucu karşılaştırmak! Basit bir kodla bu işlem halledilebilir
if( MD5(i) == “c84f093c22580a70813dff7d0e9c85bf” )
print( “Åžifre bulundu: ” + i);
Yukarıdaki döngü milisaniyeler içinde tamamlanıp, eğer varsa, sonucu listeleyecektir. Ancak tabii ki şifre 6 basamaklı bir sayı olacak varsayımını her zaman yapmamız mümkün değildir. Şifrelerde büyük harfler [A-Z], küçük harfler [a-z], rakamlar [0-9], özel karakterler [!@#$%^&*()-_+=], veya dile özel karakterler [ıçşüğâî] bulunabilir. Uzunlukları ve karakter tipleri belli olmayan bir şifre için brute force saldırı uygulamak tahmin ettiğinizden de uzun sürebilir (milyarlarca yıl mesela). Bu yüzden bazı karakter setleri için MD5 şifreleri tabloları hazırlanır.
MD5 Tabloları ve RainbowCrack Projesi
Biraz önce dediğimiz gibi; MD5 şifrelerini kolayca eşleştirmek için tanımlayacağımız karakter setindeki belli uzunluklarda tüm olasılıkların MD5 sonucunu bir tabloya atmak, bu eşleştirmeyi birkaç saniye içinde tamamlamak anlamına geliyor. Yalnız bu tabloları oluşturmak için güçlü bir bilgisayara (veya paralel bilgisayarlara), geniş bir disk alanına ve gerekiyorsa uzun zamana ihtiyacınız olacaktır. Bir kez tabloyu oluşturduğunuzda vereceğiniz herhangi bir MD5 sonucunu eşleştirmek gayet hızlı olacaktır. RainbowCrack projesinden birkaç örnekle konuyu açıklayalım:
Örnek #1
| karakter seti | [ABCDEFGHIJKLMNOPQRSTUVWXYZ] |
| ÅŸifre uzunluÄŸu | 1-14 |
| olasılık | 8353082582 |
| tablo boyutu | 610 MB |
Örnek #2
| karakter seti | [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789] |
| ÅŸifre uzunluÄŸu | 1-14 |
| olasılık | 80603140212 |
| tablo boyutu | 3 GB |
Örnek #3
| karakter seti | [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_+= ] |
| ÅŸifre uzunluÄŸu | 1-14 |
| olasılık | 915358891407 (2^39.7) |
| tablo boyutu | 24 GB |
Bu tablolar içinden bir windows şifresi saniyeler içinde bulunabiliyor. Windows şifrelemesi için büyük harflerden oluşan karakter setleri küçük harfleri de kırabildiği için ayrıca küçük harfler eklenmemiş.
Örnek #4
| karakter seti | [abcdefghijklmnopqrstuvwxyz0123456789] |
| ÅŸifre uzunluÄŸu | 1-8 |
| olasılık | 2901713047668 |
| tablo boyutu | 36 GB |
Yukarıdaki örnekte ise tablo MD5 için hazırlanmış ve karakter seti küçük harflerden ve rakamlardan oluşmaktadır. Verilen MD5 sonucu birkaç dakika içinde eşleştirilip %99.9 ihtimalle bulunabiliyor.
Bu MD5 tablosunda karakter setine büyük harfler ve özel karakterler eklendiğinde tablo boyutu terabaytlar düzeyine çıkacak; 9 ve 10 karakter uzunluğundaki şifreleri de kapsamasını istersek hem tablonun oluşturulması aylar belki yıllar sürecek, hem de boyutu düşünemeyeceğimiz kadar büyük olacaktır.
İnternette MD5 şifrelerinin ne olduğunu sorabileceğiniz birkaç veritabanı mevcut. Ne kadar yasal bir uygulamadır tartışılır tabii ki ama vermek için bir sakınca görmüyorum:
Sayın Ferruh Mavituna da güzel ve kapsamlı bir liste hazırlamış, iyisi mi siz bu listeden yararlanın.
İnternet Uygulamalarında MD5 Kullanarak Daha Güvenli Şifre Saklama
Sıklıkla takip ettiÄŸimiz fazlamesai.net sitesinde temmuz ayı sonunda bir açık bulunmuÅŸ ve tüm veritabanına eriÅŸilmiÅŸti. Veritabanında ÅŸifreler tabii ki açıkça yazmıyor, veya geri dönüşümü olan bir ÅŸifre algoritmasından geçirilmiyordu. Kullanılan algoritma MD5 olmasına raÄŸmen tabii ki kimsenin içi rahat deÄŸildi; çünkü artık MD5 ÅŸifreleri internetteki MD5 lookup table‘lar sayesinde kolayca eÅŸleÅŸtirilebiliyordu. Bir saldırının anatomisi: Fazlamesai yazısını ve yorumlarını okuyacak olursanız güvenlikle ilgili faydalı bilgiler edinebilirsiniz.
MD5 ÅŸifrelerini saÄŸlamlaÅŸtırmak için insanların akıllarına ilk gelen yöntem MD5 sonuçlarını tekrar tekrar MD5′ten geçirmek olmuÅŸ. Yani veritabanına kaydederken md5(ÅŸifre) yerine md5(md5(md5(ÅŸifre))) olarak kaydetmeye baÅŸlamışlar. Ancak dikkat edin, bu yöntemle ÅŸifrenizin bulunma zamanını ve RainbowCrack tablosunun uzunluÄŸunu exponential deÄŸil linear büyütmüş olursunuz!
Åžifreleri daha güvenli saklamak için MD5′ten geçirmeden önce aldığınız karakter dizisine bazı iÅŸlemler uygulayın. Mesela:
- Åžifreyi reverse edin, normaliyle birleÅŸtirin.
- Şifrenin ilk veya son birkaç karakterini başa veya sona ekleyin.
- Şifrenin başına ve sonuna farklı karakter setlerinden belirleyeceğiniz karakterleri ekleyerek şifreyi uzatın.
Uygulama
Gelin, isterseniz bir uygulama yapalım. Diyelim ki elimizdeki ÅŸifre 1234 (sanırım insanların %10′u filan bu ÅŸifreyi kullanır). İsterseniz bu ÅŸifreyi MD5 sonucundan nasıl rahat bulabildiÄŸimize bakalım:
Åžifremiz 4 basamaklı bir sayı, demek ki 1′den 4 basamaÄŸa kadar olan sayıların MD5 hash’lerini bulup karşılaÅŸtırsak ÅŸifreyi bulabilecekmiÅŸiz. Olasılık sayısı (9^1)+(9^2)+(9^3)+(9^4) = 7380. İşlemcinin yorulduÄŸuna bile deÄŸmez… Zaten bu ÅŸifrenin nasıl kolayca eÅŸleÅŸtiÄŸini buradan ve buradan kontrol edebilirsiniz.
Şimdi ise şifremizi MD5 fonksiyonuna sokmadan önce birkaç işlem uygulayalım:
- Öncelikle şifreyi ters çevirin: 4321
- Başına birkaç sayı ve karakter ekleyin (mesela 0a4b): 0a4b4321
- Son iki karakterini alıp başa ekleyin: 210a4b4321
- Başına ve sonuna büyük-küçük harfler ve özel karakterler ekleyin
(mesela başına 2%t}W, sonuna da a(H_5$ gibi…) : 2%t}W210a4b4321a(H_5$ - Åžimdi ise bu karakter dizisini MD5 fonksiyonundan geçirin:
md5(2%t}W210a4b4321a(H_5$) = f56ae31a4ebd33c0fee2054f9567d201
Bu hash değerini internetteki veritabanlarının bulmasının imkanı yok! Hem 20 karakterli, hem de çoğu karakter setinden harfler içeriyor. Hoş, biri bulsa bile 2%t}W210a4b4321a(H_5$ diye bir şifre hiçbir işine yaramayacaktır. Burada önemli olan,
- Aldığınız şifreyi her zaman aynı basamaklardan geçirerek kontrol etmek,
- Bu basamakları gizli tutmak.
Böylece kullanıcılarınızın şifrelerini daha güvenli saklayabilirsiniz.
Yorumlar - Başa Dön
26 AÄŸustos 2006
Mükemmel bir yazı olmuş, gerçekten tebrik ederim. Aynı dediğiniz gibi bende 3 kere Md5 kullanacaktım, şu an elimdeki proje için ama daha iyi bir yöntem varmış. :) Hiç aklımdan bile geçmemişti.
Teşekkürler.
29 AÄŸustos 2006
Bu bahsettiğiniz yöntemde ciddi anlamda geliştirilmeli, yoksa md5 çözüldükten sonra burdaki algoritmada çözülebilir.
Ama bencede iyi bir yaklaşım olmuş.
1 Eylül 2006
[...] Acemi Blogcu Yakuter ve Dmry gene tam gaz devam. A辫 Bilgi Onur Kí¨¼ktunç¡‚ey tatil dç¯¼ï¼ gí»¥l yazî¡r yazmî¾® Pazarlama bloglarí¡«arnaval nedeniyle canlandí® Sayî® Mehmet Do᢮’î® gí»¥l yazî¡rí¡§e華li forumlarda yer alr. Kendinsinden yeni yazî¡r bekliyoruz. [...]
10 Eylül 2006
exponential ve linear büyümeye açıklık getirirmisiniz?
10 Eylül 2006
Hay hay. Belirlediğimiz bir karakter seti için RainbowCrack tablo oluşturmak istiyoruz. Normalde 1-n arası uzunluktaki şirfeler için bu tablo t zamanda tamamlanıyorsa, her bir kelime için x kere MD5 algoritmasından geçirip kaydetmek xt zamanda tamamlanacaktır (tabii ki buna bağlı olarak tablonun boyutu da x katına çıkacaktır). Yani hem zaman hem de boyut olarak tablonun oluşturulması x ile orantılı linear bir artış gösterecektir.

Örnek olarak 30 karakter içeren setimiz için 8 karakter uzunlukta yazabileceÄŸimiz kelime sayısı 30^8′dir. Åžifreyi örnek olarak 3 kere algoritmadan geçirdiÄŸinizde olasılık sayısı 3x(30^8) olacaktır. Bu noktada ÅŸifremizin uzunluÄŸunu bir karakter artırmak, olasılık sayısını (30^9) 30 katına çıkaracaktır. Yani 30 kere MD5′ten geçirmek yerine 1 karakter ekleyerek ÅŸifrenin çözülmesini eÅŸit oranda zorlaÅŸtırabiliyorsunuz. Olasılığın üs ÅŸeklinde artmasına exponential büyüme denir, ve üs büyüdükçe sayılar da inanılmaz ÅŸekilde büyümeye devam eder.
Sub-exponential büyümeyi ise karakter setimizi büyüttüğümüzde görürüz. EklediÄŸimiz karakter 30 karakterlik set içinde yoksa olasılık sayısı (30^9)’dan (31^9)’a çıkar ki bu hem exponential hem de sub-exponential bir büyümedir.
Linear, sub-exponential, ve exponential büyüme grafikleri yanda mevcut. Sonuç olarak exponential ve sub-exponential büyümeler bize linear büyümeden çok daha büyük bir artış kazandıracaktır.
13 Eylül 2006
“PHP Security Consortium”da bununla ilgili bir yazı var. Åžiddetle okumanızı tavsiye ederim.
http://phpsec.org/articles/2005/password-hashing.html
Bu arada Onur’un yazısı da çok güzel. Tebrik ederim.
26 Aralık 2006
Güzel bir yazı, teşekkürler.
Yalnız kaynak kodun ortaya çıkması halinde exponential büyümenin muazzam etkisinin ortadan kalktığınıda unutmamak lazım.
3 Eylül 2007
eger md5 kesin kırılacaksa size istediginiz sitenin admininin md5 vereyim cok ugrasıyom ama olmuyo ÅŸifre uzun oldukca yada zor oldukca kırılması cok daha zorlasıyo iÅŸlh bigün mantıgı çözülür…
12 Eylül 2007
[...] [...]
5 Aralık 2007
“pardus-1.0.iso dosyasının MD5 sonucunu gösteriyor. EÄŸer siz bu 700mb’lık dosyayı bilgisayarınıza indirirken 1 bit’lik bile hata yapmış olsaydınız MD5 sonucu çok farklı bir sayı çıkardı!”
pardusu indirdiğimizde yazılan hash ile nasıl karşılaştırma yapılıyor bir programı mı var ?
20 Aralık 2007
[...] ettiyseniz oluşturduğunuz şifreye yeni bir karakter setinden eleman eklemediniz. Güvenli MD5 Kullanımı yazımda belirttiğim gibi, şifrenize rakamlar ve özel karakterler eklemeniz şifrenizin [...]
23 Aralık 2007
saol arkadaşım bende uzun zamandır sesion md5 komutlu login sistemleri kullanıyorumdum şu güne kadar hiç bi sorunla karşılaşmadım ama :( bundan sonra daha farklı bişeler kullanıcam
11 Ocak 2008
[...] ettiyseniz oluşturduğunuz şifreye yeni bir karakter setinden eleman eklemediniz. Güvenli MD5 Kullanımı yazımda belirttiğim gibi, şifrenize rakamlar ve özel karakterler eklemeniz şifrenizin [...]
23 Mayıs 2008
saÄŸol kaliteli bilgiler..
17 AÄŸustos 2008
[...] ettiyseniz oluşturduğunuz şifreye yeni bir karakter setinden eleman eklemediniz. Güvenli MD5 Kullanımı yazımda belirttiğim gibi, şifrenize rakamlar ve özel karakterler eklemeniz şifrenizin [...]
19 AÄŸustos 2008
[...] ettiyseniz oluşturduğunuz şifreye yeni bir karakter setinden eleman eklemediniz. Güvenli MD5 Kullanımı yazımda belirttiğim gibi, şifrenize rakamlar ve özel karakterler eklemeniz şifrenizin [...]
4 Eylül 2008
Sql injection ve bu yazınızı okudum çok güzel tam aradığım bilgiler güvenlik konusunda yeni yazılarınızı bekliyorum sık kullanılanlara ekliorm sizi:) kolay gelsin
14 Eylül 2008
[...] ettiyseniz oluşturduğunuz şifreye yeni bir karakter setinden eleman eklemediniz. Güvenli MD5 Kullanımı yazısında belirttildiği gibi, şifrenize rakamlar ve özel karakterler eklemeniz şifrenizin [...]
9 Ekim 2008
Ben bir ÅŸifreyi iki defa md5′e çeviriyorum. Bu yeterli olur mu?
md5(md5(sifre))
11 Ekim 2008
Arkadaslar Harika seyler yazmissiniz. Ancak benimde eklemek istediklerim var. MD5 ile sifrelemeden önce başına sonuna karakterler eklemek cok guzel hele hele sifreyi uzatarak bulunmasini zorlastirmak bile tek basina yeterli olacaktir. Ancak bir tablo olduÄŸunu ve bu tabloda binlerce kayıt olduÄŸunu varsayalım. eÄŸer veri tabanına erismeyi ve sizin md5 olarak kayıtlı ÅŸifrelerinizden bir kaç tanesini çözmeyi baÅŸarırsa 100 ‘de 1 milyon ÅŸifrelerin arasındaki benzerlikten yola cıkarak sizin tarafınızdan eklenen karakter setlerini kolayca program bile yazmadan ayıklayabilir. Bu sebeple md5 kullanmadan önce tarihe göre duyarlı ön ÅŸifreleme function yazabiliriz. Sifrenizin murat oldugunu varsayalim. Öncelikle tüm harfleri karşılık gelen baÅŸka bir harf ile eÅŸleyelim. m=a, u=s, r=g.. gibi.. basit bir ÅŸifreleme yapalım.(bunun sebebi uzun ÅŸifremizdeki bazı harflerin arka arkaya gidiÅŸinden anlamlı bir kelime cıkmasın) Ayın 21 i ve saat 16:20 nin ÅŸifreleme tarih ve saati oldugunda düşünelim. 2 için % ve 1 içinde + karakterini ÅŸifremizin ilk harfinden sonra ekleyelim. tabiki 1..9 arasında rakamların hepsi farklı karakterler alacaktı. aynı ÅŸekilde “16:20″ 5 karakterlik setin her bir karakteri için ise a..z ye kadar farklı deÄŸerler vererek bir karakter seti oluÅŸturalım ve bunu ÅŸifremizin ikinci karakterinin arasına yerleÅŸtirelim. daha sonra ÅŸifremizin en sonuna ayın günüyle baÄŸlantılı uzunlukta ve içeriÄŸe sahip bir karakter seti ekleyelim. ve yine o anki saate göre uzunluÄŸu ve içeriÄŸi deÄŸiÅŸen bir karakter setinide ÅŸifremizin en sonuna ekleyelim.
Şifrenin Çözülmesi :
ÅŸifreyi geri okurken ilk iki karakter bize ayın gününü verecek ve bir karakter sonraki 5 karakter ise saati.. ayın günü ve saatine göre en sona eklenen karakter uzunlukları belli oldugu icin kaç karakterin sondan silinecegini bulmuÅŸ olacaksınız. ve sonrada ilk yaptıgınız basit ÅŸifrelemeyi geri cevireceksiniz.. buda benim kullandıgım bir yöntem..Tarih ve saate duyarlı olması hiç kullanılmayan bir yöntem oldugu icin hiç de denenmiyor….. kolay gelsin hepinize…
13 Aralık 2008
[...] Kaynak (DeÄŸer BiçilmemiÅŸ!) Loading … [...]
23 Aralık 2008
[...] Kaynak Alıntıdır Etiketler: MD5, MD5 Algoritması Nedir?, MD5 ve Güvenli Kullanımı  [...]