Tek Yönlü Fonksiyon ve Veri Şifreleme Hk

Değerli üstatlar merhaba. Accounts.py’de oluşturduğum kullanıcının parolasını sha256 ile şifreliyorum.

Örneğin ;

Accounts.py

test = UserRepository()
password = "123456"
convertShaPassword = GeneralSecure.SecurePassword.hash_password(password)
user = Account('0', 'Ahmet', 'BLOM', 'lisanne@gmail.com', 'Counselor', 'e', convertShaPassword, '0', '0')
test.accountRegister(user)

Oluşturmuş olduğum kullanıcının bu bilgilerini Database.py ile veritabanına gönderiyorum ;

Database.py

class AcceptVeriable:

    def __init__(self):
        self.accountList = []
        with open("AccInformation.json", "r", encoding="utf-8") as file:
            veriable = json.loads(file.read())
            count = 0

            while count < len(veriable):
                self.accountList.append(veriable[count]['user_id'])
                self.accountList.append(veriable[count]['firstName'])
                self.accountList.append(veriable[count]['lastName'])
                self.accountList.append(veriable[count]['username'])
                self.accountList.append(veriable[count]['password'])
                self.accountList.append(veriable[count]['email'])
                self.accountList.append(veriable[count]['accessLevel'])
                self.accountList.append(veriable[count]['accountKEY'])
                self.accountList.append(veriable[count]['register_date'])
                self.sendData()
                self.accountList.clear()
                count +=1

    # Verileri veritabanına gönder    
    def sendData(self):
        db = sqlite.connect("zyro.db")
        im = db.cursor()
        im.execute("""CREATE TABLE IF NOT EXISTS 
                     staff_management(user_id, firstname, lastname,
                     username, password, email, access_level, acc_key, reg_date)""")

        # Liste halinde tek seferde gönder.
        transferToDB = self.accountList
        im.execute("""INSERT INTO staff_management VALUES

                      (?, ?, ?, ?, ?, ?, ?, ?, ?)""", transferToDB)

        db.commit()

        # Json Dosyasında bekleyen verileri sil.
        open('AccInformation.json', 'w').close()

Login.py ilede işte bildiğiniz gibi veritabanından bazı sorgulamalar yapıp (kullanıcı adı, şifre doğruluğu gibi) giriş yapılmasını sağlamak istiyorum.

Ancak ne yaptıysam yapayım başaramadım :slight_smile: tek yönlü fonksiyon ile veriyi şifreledikten sonra ayarlayamadım girişi nasıl yapabileceğini.

Login.py

# Aktif Kullanıcı    

    def activeUser(self, username='[System]'):

        self.username = username

        return self.username

        

    # TODO: Don't forget here, there will be a password query online // GERİ GEL BURAYI TAMAMEN GÜVENLİ HALE GETİR. + Admin şifre için Ayrı kontrol sınıfı oluştur.

    def loginFunction(self):      
        data = sqlite.connect('zyro.db')
        im = data.cursor()
        self.txtUsername = self.tboxUserName.text() # Test
        self.txtPassword = self.tboxPassword.text() # Test
       
        im.execute("""SELECT username, password FROM staff_management WHERE
                   username = ? AND password = ?""", (self.txtUsername, self.txtPassword))
        login = im.fetchone()

        if login:
            self.lblLoginSuccess.setText("Bilgiler doğrulandı, giriş sağlanıyor.")
            self.WaitingPanel()
            self.activeUser(self.txtUsername)
            userRepo = UserRepository()
            userRepo.IsLoggedIn = True
            userRepo.currentUser = self.txtUsername
            Login.transactionUser.append(self.txtUsername) # TODO: GERİ GEL BURAYI DETAYLANDIR.
            Logs.JoinSystemLog(self.txtUsername) # Join Log
                  
        else:
            self.lblLoginSuccess.setText("Bilgilerinizi tekrar kontrol edin...")

Bu konuda yardım edebilir misiniz lütfen ?

Ayrıca, şifreleme için kullandığım GeneralSecure.py :

import hashlib
import uuid

class SecurePassword:
    def hash_password(password):
        salt = uuid.uuid4().hex
        return hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt
    
    def check_password(hashed_password, user_password):
        password, salt = hashed_password.split(':')
        return password == hashlib.sha256(salt.encode() + user_password.encode()).hexdigest()

    # new_pass = input('Please enter a password: ')
    # hashed_password = hash_password(new_pass)
    # print('The string to store in the db is: ' + hashed_password)
    # old_pass = input('Now please enter the password again to check: ')
    # if check_password(hashed_password, old_pass):
    #     print('You entered the right password')
    # else:
    #     print('I am sorry but the password does not match')

Login.py’de bu girişi nasıl sağlayabilirim ? Şu örnekte ;
if check_password(hashed_password, old_pass):
şifrelenen veri ve girilen şifreyi parametre olarak vermiş evet ama Accounts.py’den bunları nasıl alabilirim ? Daha sonraki girişlerde problem olmayacak mı :S

Merhaba,

Öncelikle şunu söyleyeyim 1 metni hashlediğinizde bunun geri dönüşü yoktur.
Sizin burada yaptığınız hata hashlediğinizde çıkan string ile tekrar hashlediğinizde çıkan stringin aynı olacağını varsaymanızdan dolayı oluyor. Bunu aynı olduğunu varsaydınız için databaseden password ve kullanıcı adı eşleşenleri çekiyorsunuz :slight_smile: Bu yanlış bir metod.

Yapmanız gereken o kullanıcının şifresini DB den çektikten sonra
check_password(dbden_gelen_hashlenmiş_pw, kullanicinin_girdigi_pw) (kullanicinin girdiği şifreyi verirken hashli bir şekilde vermeyeceksiniz yalın direkt girildiği hali ile vereceksiniz) olarak bu ikisini kontrol edeceği bir fonkisyon yazmanız gerekiyor. Kullandığınız kütüphaneye pek aşina değilim o yüzden bir şey diyemiyorum ancak internet üzerinden bunu yapacak bir sürü kod parçası bulabilirsiniz.

Kolay gelsin

1 Beğeni

Değerli yanıtınız için teşekkür ederim hocam. Hocam evet söylediklerinizde tamamen haklısınız, hatta GeneralSecure.py’de şöyle bir örnek var ;
if check_password(hashed_password, old_pass):

Dediğinizi anladım evet ama sorun şurada ; O an Accounts.py’de oluşturulan kullanıcının şifresini(“123456”) nasıl Login.py’ye döndürebilirim ? Çünkü hashed_password kısmını verebilmem için Login.py’den o şifreye ulasabilmem gerekiyor ki veritabanında işlem yapabileyim. Veritabanı kısmı tamamen kafamı karıştırıyor. Bugün bir örnek buldum vaktim olmadı pek bakamadım eve geçince o örneğe bakıcam veritabanıyla alakalı bir örnek verilmiş. Eğer dediğim gibi bir örnekse buradada paylaşırım günün birinde birilerinin işine yarayabilir.

Şöyle olacak, kullanıcı register olduğunda hashlediğin şifreyi veritabanında tutacaksın (yani hashed_password veritabanında password sütununda kayıtlı olacak). Kullanıcı login olduğunda ise o kullanıcı adı ile sqlde arama yapacaksın ve hashed_password çekeceksin :slight_smile: Daha sonra kullanıcının girdiği password ile hashad_passwordu fonksiyona vereceksiniz :smiley: Gayet net adımlar. Nerede takıldığını ben mi kaçırıyorum?

O an Accounts.py’de oluşturulan kullanıcının şifresini(“123456”) nasıl Login.py’ye döndürebilirim ? Çünkü hashed_password kısmını verebilmem için Login.py’den o şifreye ulasabilmem gerekiyor ki veritabanında işlem yapabileyim

yani şöyle accounts pyda kullanıcının 123456 şifresini 1 defa aldıktan sonra hashleyecek ve o şekilde kaydedeceksin. Artık bu “123456” şifresi hashli bir şekilde veritabanında saklanacak. Orada old_pass yazması yanlış sen eski girdiğin şifreyi almak istiyorsun ancak metod öyle çalışmıyor :slight_smile: Orada hashed_password (dbye kaydettiğin) ve login olurken girilen passwordu vermen gerekiyor :slight_smile:

2 Beğeni

Hocam evet aslında ilk bakışta adımlar gayet net :smiley: zira benim için adımın saptığı nokta tam olarak doğrulamada başlıyor. Şimdi şuradaki örneğe bakarak ilerledim ; Python and SQLite

Ona istinaden yazdığım giriş fonksiyonu ;

def loginFunction(self):

        

        data = sqlite.connect('zyro.db')

        im = data.cursor()

        self.txtUsername = self.tboxUserName.text() # Test

        self.txtPassword = self.tboxPassword.text() # Test

        currentUser = self.txtUsername

        pw = self.txtPassword

        currentHash = SecurePassword.hash_password(pw)

        t = (currentUser,)

        

        im.execute("""SELECT password FROM staff_management WHERE username=?""", t)

        row = im.fetchone()

        

        if row is None:

            print("Account bulunamadı.")

        else:

            fetchedHash = row[0]

            

        if fetchedHash == currentHash:

            print("Giriş başarılı.")

        else:

            print("Başarısız giriş.")

Şimdi ben giriş yapmak istediğim kullanıcıyı Accounts.py’de oluşturuyorum, orada zaten bir hashleme işlemine sokuyorum, sanırım birde burada hashleme işlemi yapıp bu şekilde giriş yapmasını sağlamaya çalışıyorum ve asla birbirini tutmayacağı için, koşul sağlanamıyor giriş yapamıyorum. (Bunu zaten sizde önceki yorumlarınızda söylediniz). E bu bir server diyelim. Kullanıcı, sallıyorum internet üzerinden kayıt oldu ben her defasında nasıl işlem yapıcam ki? Olmuyor yani tutmuyor. Ilk oluşturulan hash’i buraya nasıl vericem? Ya da onu nerde tutacam da buraya aktarıcam her defasında da bir karşılaştırma yapıcam? işler burada karışıyor :smiley: Allah aşkına mümkünse bana kodun doğrusunu yazabilir misiniz? veritabanı işleri tamamen karıştırdı

Merhaba,

kod yazamam :slight_smile:

Bak tekrardan adımları yazıyorum
register
1- kullanıcı adı ve pw al
2- pw yi hashle ve kullanıcı adı ile beraber database e kaydet


  1. işlem tamamlandığında dbnde şöyle bir kayıt olacak
    kullanici_adi | şifre
    mcagrical | UIHJGI^G)(WDHG’^+
    (şifre hashlenmiş bir şifre olacak ben tamamen salladım)

login
1 - kullanıcı adı ve şifreyi al
2 - bu kullanıcı adından faydalanarak SELECT ile database üzerinden hashlenmiş şifreyi al
3 - 2. adımda database üzerinden almış olduğun hashlenmiş şifre ile 1. adımda kullanıcının girdiği şifreyi HASH KARŞILAŞTIRMA fonksiyonu ile karşıaştır.
4 - Zaten 3. adımda soktuğun fonksiyon eğer şifre ile hashli şifre eşleşiyor ise TRUE eşleşmiyor ise FALSE gönderecek.

Dostum daha detaylıda anlatamam :slight_smile: Bundan sonrası senin araştırman.

Kullanıcı, sallıyorum internet üzerinden kayıt oldu ben her defasında nasıl işlem yapıcam ki? Olmuyor yani tutmuyor. Ilk oluşturulan hash’i buraya nasıl vericem?

Burada da bak dostum sen zaten hashlediğin şifreyi database e kaydettin? Veritabanının amacı veri saklamaktır. Kullanıcılar her login olduğunda veritabanında bu kullanıcı adı var mı, varsa kullanıcı adının hashlenmiş şifresini getir şeklinde SQL komutu yazman lazım :slight_smile: Hani ben ilk oluşturulan hashi buraya nasıl getireceğim demene biraz kızdım. Veritabanı ne demek ve nasıl kullanılırı anlamamışsın. İlk önce orayı çöz sonra buraya devam et.

2 Beğeni

Ya hocam vallahi çok özür dilerim, aslında genel olarak çabuk kaparım bazı şeyleri. Ama nedense cidden çok afedersiniz mallığım tuttu anlayamadım bir türlü kafamda kuramadım mantığını. Sorunu sizin son çözümde yazdığınız 1. şunu yap, 2 bunu yap diyerek yazdığınız algoritma ile ilerleye ilerleye gittim :smiley: Ve şuan ciddi çok iyi kavradım mantığını. Çok basitmiş aslında :smiley: Son güncel hali şu kodların ;

def loginFunction(self):

        

        data = sqlite.connect('zyro.db')

        im = data.cursor()

        self.txtUsername = self.tboxUserName.text() # Test

        self.txtPassword = self.tboxPassword.text() # Test

        

        im.execute("""SELECT password FROM staff_management WHERE username = ?""", (self.txtUsername,))

        hash_pw = im.fetchone()[0]

        

        if SecurePassword.check_password(hash_pw, self.txtPassword):

            print("Giriş başarılı")

        else:

            print("Giriş başarısız")

Uğraştırdığım için çok özür dilerim tekrardan ve yardımınız için çok teşekkürler

Yok canım ne demek :smiley: Yardımcı olduysam ne mutlu bana,
sadece çabuk kaparımı düşünmekten ziyade doğru bir şekilde öğrenmeye çalış :slight_smile: sqlite ile örnek projeler izle, insanlar neler yapıyor nasıl yapıyor bunları bir gör deneyimle daha sonra kendi projelerine vakit ayırabilirsin. Yani demek istediğim konseptleri iyice öğren sonra projene ekle :slight_smile:

1 Beğeni