Şifreler hayatımızda önemli bir yer tutmaya başladı. Her yerde şifre kullanmak durumundayız. Çünkü veri değerli. Express JS ile yazdığımız uygulamalarda da kullanıcı giriş işlemleri için üye olacak kişinin bir şifre belirlemesini isteriz. Kullanılacağı yere göre de bu şifrelerin gücünü belirleriz. Karmaşık ve uzun şifreler. Peki bu güvenli mi?
Güçlü bir şifrenin daha güvenli olacak muhakkak. Fakat bununla birlikte bu şifreyi veritabanına veya bir dosyaya kayıt ettiğimizde artık onun gücünü elinden almış olabiliriz. Çünkü veritabanları veya dosyalar hacklenebilir. Yani başkasının eline geçebilir. O zaman güçlü bir şifre de olsa şifrenin bir önemi kalmayacaktır.
Üye Şifrelerini Şifreleme
Şifrelerin ele geçebilme ihtimaline binaen eğer şifreler başkasının eline geçerse onun anlamayacağı bir hale getirmek gerekir. Buna hash diyoruz. Hash ne demek? Düz bir metini alıp bakıldığında ne olduğu anlaşılmayacak ve geri getirilemeyecke şekilde şifreleme. Çünkü bir kullanıcı şifresini kayıt ettiğimizde onun ne olduğunun bir daha öğrenilememesi gerekir. Aksi halde şifreler kırılabilir.
Üye Kayıt ve Giriş İşlemlerinde Şifrelemenin Mantığı
Şifreler sonuç olarak düz metinlerdir ve herkes tarafından okunabilirler. Bu nedenle uygulamalarımızda şifreyi tek yonlu olarak tekrar şifreleyerek kayıt etmek gerekir. Tek yönlü olan bu işlem her tekrarlandığında aynı sonucu vermesi gerekir. Yani mesela şifremiz 1au_5Ie-9 şeklinde olsun. Bu şifreye hash uygulandığında şu şekilde görünebilir ksa72==flafaf911_l19kfa/. Üye kayıt olurken hash sonucu veri tabanına kayıt edilir.
Sonrasında üye giriş yaptığında üyenin girdiği şifreye tekrar hash uygulanır ve veri tabanındaki kayıt ile karşılaştırılır. Eğer ikisi eşit ise kullanıcı doğru şifre girmiş demektir ve sisteme girişine izin verilir. Çünkü bir seçilen bir metin için hash sonucu her zaman aynı olmak zorundadır.
Bcrypt Kütüphanesi
Şifreleme işlemi yapan çok sayıda kütüphane mevcuttur. Hepsinin kendine göre olumlu veya olumsuz tarafları olabilir. Express JS ile en çok kullanılan kütüphane Bcryptdir. Girilen metine hash işlemi uygular. Bir çok şifreleme kütüphanesinin aksine bu kütüphanenin özelliği şifreleme işlemini yavaş yapmasıdır. Evet yavaş yapması, çünkü bu da bir güvenlik önlemidir. Seçilen parametrelere bağlı olarak şifreleme işlemi için geçen süre dakikalar olarak ayarlanabilir.
Yavaş çalışmasının nedeni ise güçlü bilgisayarlardır. Çünkü şifrelenmiş bir veri de kırılabilir. Bunu yapacak çok güçlü bilgisayarlar var, fakat şifrenin kendisi yavaş çalışıyorsa bilgisayarın güçlü olması birşey ifade etmez. Zorunlu olarak şifrenin hızına uymak zorunda kalır. Bu nedenle bir şifrenin kırılması oldukça zaman alıcı bir hale gelir.
Node / Express JS ile Bcrypt Kullanarak Üye İşlemleri Nasıl Yapılır?
Şimdi bu girişten sonra üye işlemeleri için şifrelemenin nasıl kullanılacağını adım adım inceleyelim. İlk olarak projemize bcrypt kütüphanesini dahil etmemiz gerekiyor. Bunu normal bir npm modulü kurar gibi yapabiliriz.
npm i bcryptKayıt Olurken Üye Şifresini Şifreleme
Şimdi bir kullanıcı kayıt olurken onun şifresini nasıl şifreleyeceğimizi görelim.
const bcrypt = require("bcrypt");
const password = "1yuUR_keW.l";
const saltRounds = 10;
bcrypt.hash(password, saltRounds, (err, hash) => {
// Burada hash değerini kayıt edebilirsiniz.
// hash, şifrelenmiş sifre
// err, eğer varsa hata bilgisi
})Burada saltRounds dikkatinizi çekmiştir. salt bir şifrenin ne kadar uzun sürede oluşturulacağını belirtir. Ne kadar büyük olursa şifrenin oluşturulması o kadar uzun sürer. Yukarıdaki kullanımda salt değeri girilen saltRounds değeri kullanılarak otomatik oluşturulur. İstenirse bcrypt.genSalt ile kendimiz de oluşturabiliriz. Örnek kullanımı
bcrypt.genSalt(saltRounds, function(err, salt) {
bcrypt.hash(myPlaintextPassword, salt, function(err, hash) {
// Burada hash değerini kayıt edebilirsiniz.
});
});Üye Giriş Yaptığında Şifre Kontrolü Yapma
Üye kayıt olurken şifrenin nasıl hash edileceğini gördük. Şimdi ise kayıt olmuş bir üyenin girdiği şifrenin (düz metin olarak) alınarak daha önce kayıt edilmiş hash bilgisi ile denetlenmesini görelim. Bunun için bcrypt.compare metodunu kullanıyoruz.
Bunun için önce veritabanında ( veya nereye kayıt edildi ise) hash edilmiş şifreyi alıyoruz ve sonrasında giriş yapan üyenin gönderdiği şifreyi alıyoruz, compare metoduna gönderiyoruz, bu metod gönderilen düz şifreyi önce hash ediyor ve veri tabanından gelen hash edilmiş şifre ile karşılaştırıyor. Eğer ikisi eşit ise true aksi halde false değerini dönderir.
// Veritabanında kayıtlı olan hash edilmiş şifreyi alarak
// hash değişkenine ata
// Üyeden gelen şifreyiyi
// password değişkenine ata
// bu iki değişkeni bcrypt.compare ile karşılaştır
bcrypt.compare(password, hash, function(err, result) {
// result === true ise şifre doğru giriş yaptır
// result === false ise hatalı şifre uyarı ver
});Bcrypt Senkron ve Asenkron Çalışma
Bcrypt ile işlem yapmak belirli bir zaman alır. Bu süreyi artırabilir veya azaltabiliriz. Ayrıca Bcrypt hem senkron ve hemde asenkron olarak da çalışabilir.
Senkron Çalışma
Eğer sıralı bir işlem yapmak istiyorsak hashSync metodunu kullanabiliriz. Bu metod düz şifreyi ve saltRounds değerini alarak hash edilmiş sonucu gönderir. saltRounds bir tamsayıdır genel kullanım olarak 10 değeri atanabilir. Bu değer arttıkça şifreleme süresi artacak, bu değer azaldıkça da şifreleme süresi azalacaktır.
const hash = bcrypt.hashSync(password, saltRounds);
// hash değerini uygun bir ortamda (mesela veritabanı) saklaKarşılaştırma için ise compareSync kullanılır.
// Üyenin gönderdiği şifreyi passpord değişkenine ata
// Veritabanından hash edilmiş şifreyi al ve hash değişkenine ata
// Sonra karşılaştır, sonuç doğru ise true
// sonuç yanlış ise false değeri dönecektir.
bcrypt.compareSync(password, hash); // true veya falseAsenkron Çalışma
Gerek promise ve gerekse async – await olarak kullanılabilir.
Kayıt için
bcrypt.hash(password, saltRounds).then(function(hash) {
// Hash edimiş değeri veritabanına ekle.
})Karşılaştırma için
// Önce veritabanından hash değerini al
bcrypt.compare(password, hash).then(function(result) {
// result === true ise girişi doğrula
// resutl === false ise hata mesajı ver
});Şeklinde kullanılabilir.
Sonuç
Veri güvenliği önemlidir, bu nedenle şifreler kayıt edilirken tek yönlü şifrelenerek kayıt edilmelidir. Bcrypt şifreleri tek yönlü kayıt eder, diğer şifreleme yöntemlerinden başlıca farkı ise şifreyi hash ederken bu işlemi uzun bir sürede yapar. Bu da eğer veritabanı ele geçirilirse, şifrelenmiş bir şifrenin kırılmasını oldukça zorlaştırır.
Siz üye işlemlerinde hangi şifreleme yöntemini kullanıyorsunuz?
