Şifre güvenliği

Kullanıcının şifre bilgilerini nasıl saklayabiliriz

Şifre güvenliği

Kullanıcının şifre bilgilerini sunucu üzerinde düz metin olarak saklamak, güvenlik açığı oluşturabilir.

Şifre bilgilerini sunucu üzerinde saklamayacağız.

Şifreyi sadece kullanıcı bilecek.

Biz de bilmeyeceğiz.

Biz sadece SHA-256 algoritması ile o şifre metninden oluşturduğumuz tekli anahtarları saklayacağız.

Bu algoritma tek taraflı olduğu için şifrenin ne olduğunu biz de bilmiyoruz. Girilen şifreden tek yönlü bir anahtar üretiliyor.

SHA-256 algoritması ile nasıl tekli anahtar oluşturulduğunu bu makaleyi okuyarak öğrenebilirsiniz.

Bu derste biraz sondan başa doğru gideceğiz.

Tekli anahtar kullanarak şifreleri sakladığımızda MongoDB kullanıcı kayıtlarının nasıl göründüğünü aşağıda görebilirsiniz.

Vibe.d şifre güvenliği

Eğer isteseydik tekli anahtarları onaltılık sayı biçiminde metin halinde de saklayabilirdik.

Ancak burada öğrenme ve deneme amaçlı olarak anahtarın kendisini ikili olarak sakladık.

Uygulamanın kaynak kodu

Uygulamanın kaynak kütüğünü ve tekli anahtar oluşturan kütüğü buradan indirebilirsiniz.

Uygulamada yaptığımız değişikliklere bakalım.

import vibe.vibe;
import vibe.db.mongo.mongo;
import std.datetime.systime : SysTime, Clock;
import anahtar.teklianahtar;

struct Kullanıcı
{
    @name("_id") int no;
    string isim;
    string eposta;
    string kullanıcı;
    ubyte[32] şifre;
    string çeşni;
    SysTime oluşturmazamanı;
}

int sonrakiKaydaGeç(string isim)
{
    auto veritabanı = connectMongoDB("127.0.0.1").getDatabase("kiraz");
    auto sayaç = veritabanı["sayaç"];
    auto sonuç = sayaç.findAndModifyExt(["_id": isim], ["$inc": ["değer": 1]], ["new": true]);
    logInfo("Sonuç %s", sonuç);
    return sonuç["değer"].get!int;
}

void kullanıcıOluştur (HTTPServerRequest istek, HTTPServerResponse yanıt)
{
    import std.array:empty;

    string isim = istek.form.get("isim");
    string ePosta = istek.form.get("eposta");
    string kullanıcıİsmi = istek.form.get("kullaniciismi");
    string şifre = istek.form.get("sifre");
    string şifreTekrar = istek.form.get("sifretekrar");

    logInfo("Alınan bilgiler İsim = %s Eposta = %s", isim, ePosta);

    if (isim.empty || ePosta.empty || şifre.empty || şifre != şifreTekrar)
        yanıt.redirect("/kayıtol");
    else
    {
        auto veritabanı = connectMongoDB("127.0.0.1").getDatabase("kiraz");
        auto kullanıcılar = veritabanı["kullanıcılar"];

        Kullanıcı yeniKullanıcı;
        yeniKullanıcı.no = sonrakiKaydaGeç("kullanıcıno");
        yeniKullanıcı.isim = isim;
        yeniKullanıcı.eposta = ePosta;
        yeniKullanıcı.kullanıcı = kullanıcıİsmi;
        auto çeşni = çeşniÜret();
        auto anahtar = tekliAnahtarÜret(şifre, çeşni);
        yeniKullanıcı.şifre = anahtar;
        yeniKullanıcı.çeşni = çeşni;
        yeniKullanıcı.oluşturmazamanı = Clock.currTime();
        assert(anahtarıDoğrula(anahtar, şifre, çeşni));
        kullanıcılar.insertOne(yeniKullanıcı);
        yanıt.redirect("/");
    }
}

void main()
{
    auto yolAtayıcı = new URLRouter;
    yolAtayıcı.get("/", staticTemplate!"gunluk/index.dt");
    yolAtayıcı.get("/kayıtol", staticTemplate!"kullanici/olustur.dt");
    yolAtayıcı.post("/kullanıcı/oluştur", &kullanıcıOluştur);
    yolAtayıcı.get("*", serveStaticFiles("public"));
    auto ayarlar = new HTTPServerSettings;
    ayarlar.port = 8080;
    ayarlar.bindAddresses = ["::1", "127.0.0.1"];
    listenHTTP(ayarlar, yolAtayıcı);

    logInfo("Lütfen tarayıcınızla http://127.0.0.1:8080/ adresini açınız.");
    runApplication();
}

Burada import anahtar.teklianahtar; ifadesi ile yukarıda bağlantı olarak paylaştığımız makalede oluşturduğumuz teklianahtar.d isimli kütüğü uygulamaya ekledik.

Kullanıcı isimli yapıda şifre alanını ubyte[32] olarak belirledik. Böylece anahtarın kendisini ikili olarak saklayabileceğiz. Ek olarak çeşni isimli bir alan ekledik.

Uygulamamızın kaynak bölümündeki değişikliklere bakacak olursak,

yeniKullanıcı.çeşni = çeşniÜret();

kısmında rastgele bir çeşni üretiyoruz.

auto anahtar = tekliAnahtarÜret(şifre,yeniKullanıcı.çeşni);
yeniKullanıcı.şifre = anahtar;

Bu kısımda da SHA256 ile yeni bir tekli anahtar oluşturuyoruz.

Kullanıcının şifre bilgilerini kaydetmediğimize dikkatinizi çekmek istiyorum.

assert(anahtarıDoğrula(anahtar, şifre, yeniKullanıcı.çeşni));

Buradaki assert ifadesini, yazılımın bunu yapacağından eminim anlamında kullanıyoruz.

Yukarıdaki kullanımda sadece tekli anahtar oluşturan işlevin değil, oluşturulan tekli anahtarı doğrulayan işlevin de doğru çalıştığını teyit etmek için kullanıyoruz.

Aksi halde yazılımın bir aykırı durum oluşturup, veritabanına kayıt yapmaması gerekir.

Yorumlar

yorum yaz

Yorum yaz

Henüz yorum yok.