Проблем с логин форма

teroristd

Registered
Здравейте, имам следния код. В базата данни имам различни потребители(различни имейли и пароли). В случая проверявам първо дали изобщо има подадено нещо в полетата ако не връщам грешка, ако да продължавам. Селектирам базата и таблицата и искам да завъртя цикъл ако подаденото от пост и реда от базата не съвпадат да върна грешка. И тук идва проблема. Винаги ми селектира първия ред от базата и спира до там. Например имам имейл1 и парола1, имейл2 и парола2. Ако сложа във формата имейл1 и парола1(демек първия ред от базата) проверките си минават. Ако сложа имейл2 и парола2 ми вади грешката че не съществуват а ги има в базата(не завърта цикъла). Не мога да кажа в заявката WHERE imeil = $dataEmail защото ако подам несъществуващ в базата имейл заявката не може да се изпълни и не се стига дори до проверките. Сигурно е нещо просто ама не мога да включа къде греша.
Код:
//$dataEmail, $dataPass са ми пост параметрите

public function start($dataEmail, $dataPass) {

        if (empty($dataEmail) || empty($dataPass)) {
            return 'empty_fields';
        }
        
        $this->prepare('USE db1')->execute();
        $sql = $this->prepare('SELECT * FROM login')->execute()->fetchAllAssoc();

        foreach ($sql as $row) {
            if ($dataEmail != $row['email']) {
                return 'wrong_email';
            } elseif ($dataPass != $row['pass']) {
                return 'wrong_pass';
            } else {
                return 'ok';
            }
        }

    }
 
Дай един вар дъмп на $sql с две полета в таблицата за да ти разпишем правилно цикъла. Проблема е че когато въведеш още един ред се получава дооооста голямо мазало тъй като ползваш foreach. Впрочем едно от решенията можеби е в заявката ти още като я подаваш:


PHP:
public function start($dataEmail, $dataPass) {

     if (empty($dataEmail) || empty($dataPass)) {
        return 'empty_fields';
    }
       
    $this->prepare('USE db1')->execute();
    $sql = $this->prepare('SELECT * FROM login WHERE email = $dataEmail AND pass = $dataPass' )->execute()->fetchAllAssoc();

    foreach ($sql as $row) {
        if ($dataEmail != $row['email']) {
            return 'wrong_email';
        } elseif ($dataPass != $row['pass']) {
            return 'wrong_pass';
        } else {
            return 'ok';
        }
    }

}

Но ако държиш да е по този ти начин в заявката трябва да разпишеш правилно цикъла.
 
Не мога да я подам така SELECT * FROM login WHERE email = $dataEmail защото както казах ако подам имейл който не съществува в базата заявката заявката не може да се изпълни, понеже ние казваме селектирай ми имейл който да е равен на подаденото от пост, и като подам нещо което го няма то няма какво да селектира и не се стига и до проверките. Ей сега ще пусна един вар дъмп.
 
teroristd каза:
Не мога да я подам така SELECT * FROM login WHERE email = $dataEmail защото както казах ако подам имейл който не съществува в базата заявката заявката не може да се изпълни, понеже ние казваме селектирай ми имейл който да е равен на подаденото от пост, и като подам нещо което го няма то няма какво да селектира и не се стига и до проверките. Ей сега ще пусна един вар дъмп.

PHP:
public function start($dataEmail, $dataPass) {

     if (empty($dataEmail) || empty($dataPass)) {
        return 'empty_fields';
    }
       
    $this->prepare('USE db1')->execute();
    if($sql = $this->prepare('SELECT * FROM login WHERE email = $dataEmail')->execute()->fetchAllAssoc()){
		foreach ($sql as $row) {
			if ($dataPass != $row['pass']) {
				return 'wrong_pass';
			}
			return 'ok';
		}
	}
	return 'wrong_email';
}

Това което казваш го заобикаляш мега лесно сам с леки промени в кода.
 
ето дъмпа на полетата first_name и email
Код:
array(3) { [0]=> array(2) { ["first_name"]=> string(4) "Ivan" ["email"]=> string(12) "asdfg@abv.bg" } [1]=> array(2) { ["first_name"]=> string(6) "Stoian" ["email"]=> string(17) "alabala@yahoo.com" } [2]=> array(2) { ["first_name"]=> string(6) "Dragan" ["email"]=> string(14) "poshta@mail.bg" } }
 
teroristd каза:
ето дъмпа на полетата first_name и email
Код:
array(3) { [0]=> array(2) { ["first_name"]=> string(4) "Ivan" ["email"]=> string(12) "asdfg@abv.bg" } [1]=> array(2) { ["first_name"]=> string(6) "Stoian" ["email"]=> string(17) "alabala@yahoo.com" } [2]=> array(2) { ["first_name"]=> string(6) "Dragan" ["email"]=> string(14) "poshta@mail.bg" } }

Пробва ли метода който ти дадох над дъмпа!? Ако не се е получил да разписваме масива . При твоят код проблема изва от последния return ok защото той прекратява всичко.
 
PHP:
public function start($dataEmail, $dataPass) {

     if (empty($dataEmail) || empty($dataPass)) {
        return 'empty_fields';
    }
       
    $this->prepare('USE db1')->execute();
    $sql = $this->prepare('SELECT * FROM login')->execute()->fetchAllAssoc();

    foreach ($sql as $row) {
        if ($dataEmail == $row['email'] and $dataPass == $row['pass']) {
            return 'ok';
        } else  if ($dataEmail != $row['email']) {
            return 'wrong_email';
        } else if ($dataPass != $row['pass']) {
            return 'wrong_pass';
        }
    }

}
 
Вторият вариант не става явно не е от return ok. Първият вариант с заявката вътре в ифа може и да стане. Сега ще го изтествам малко по обстойно.
 
teroristd каза:
Вторият вариант не става явно не е от return ok. Първият вариант с заявката вътре в ифа може и да стане. Сега ще го изтествам малко по обстойно.
Не съм сигурен но при него мисля, че можеш и без цикъл да проверяваш ето така:
PHP:
public function start($dataEmail, $dataPass) {

    if (empty($dataEmail) || empty($dataPass)) {
        return 'empty_fields';
    }
       
    $this->prepare('USE db1')->execute();
    if($sql = $this->prepare('SELECT * FROM login WHERE email = $dataEmail')->execute()->fetchAllAssoc()){
        if ($dataPass != $sql['pass']) {
            return 'wrong_pass';
        }
         return 'ok';
    }
    return 'wrong_email';
}
Ако съм прав ще ти ускори нещата малко този варянт. :)
Впрочем ако не става така $sql['pass'] така трябва да стане $sql[0]['pass'].
 
Да може и без цикъл. Засега не открих бъг работи както исках :?: мерси. Ще ти забавя точката малко че сега ще пробвам с хешовете на паролите как ще стане и може да се осера :oops: :D някъде.
 
teroristd каза:
Да може и без цикъл. Засега не открих бъг работи както исках :?: мерси. Ще ти забавя точката малко че сега ще пробвам с хешовете на паролите как ще стане и може да се осера :oops: :D някъде.
Няма проблем ти пък! И на мен колко идеи си ми давал и от теми и прочие. :?: :?: :?: За хешовете само на две места трябва да имаш! На входа към базата и на пост заявката за да ги сравниш с тази в базата тоест md5($dataPass) == $sql['pass'] като в базата вече е запаметена хеширана. :)
 
Нали преди ти казах че чета за хеширането на едно място и там казват че хеширане от типа на

md5(sha1(password))
md5(md5(salt) + md5(password))
sha1(sha1(password))
sha1(str_rot13(password + salt))
md5(sha1(md5(md5(password) + sha1(password)) + md5(password)))

е грешно и лесно се пробива. Сега хеширам с техния вариант, който наистина е добър и непробиваем може би, освен от някой много сериозен хакер. Ако имаш интерес може да ти пусна линкче, ама трябва нещо на лично че нали е забранено :) .
 
teroristd каза:
Нали преди ти казах че чета за хеширането на едно място и там казват че хеширане от типа на

md5(sha1(password))
md5(md5(salt) + md5(password))
sha1(sha1(password))
sha1(str_rot13(password + salt))
md5(sha1(md5(md5(password) + sha1(password)) + md5(password)))

е грешно и лесно се пробива. Сега хеширам с техния вариант, който наистина е добър и непробиваем може би, освен от някой много сериозен хакер. Ако имаш интерес може да ти пусна линкче, ама трябва нещо на лично че нали е забранено :) .
Честно казано изобщо не смятам, че шифъра на md5 е разбит. Реално за да се разбие една парола имай в предвид че е нужна огромна процесорна мощ за да се познае хеша. Според мен няма обратно хешираща функция на md5. Пусни ми линкче но преди доста време четох и наистина съм убеден че хеша си е неразпознаем освен ако не е някоя проста парола от типа 12456 за да се сравнят паролите и прочие.
 
Пратил съм ти линкчето ама пак закъсах :D . Аз хеширането съм го направил много по просто от тях, и вкарването на паролата в базата ми се получава но при сравнението ми дава грешка. Хеширам така. Като записвам солта отделно($passbytes) която е, рандом стринг за всеки юзър, и също $pass което е, съвкупност от двете.

Код:
$passbytes = bin2hex(openssl_random_pseudo_bytes(64));
$pass = hash( 'sha256', $passbytes . $dataPass );

После вадя така, но ми дава грешна парола.

Код:
public function start($dataEmail, $dataPass) {

        if (empty($dataEmail) || empty($dataPass)) {
            return 'empty_fields';
        }

        $this->prepare('USE db1')->execute();


        if ($sql = $this->prepare('SELECT * FROM login WHERE email=?', array($dataEmail))->execute()->fetchAllAssoc()) {
            
                //Тука вадя паролата
                $dataPass = hash('sha256', $sql['hash'] . $dataPass);
                
                if ($dataPass != $sql['pass']) {
                    return 'wrong_pass';
                }
            
            return 'ok';
        }
        return 'wrong_email';
}
 
PHP:
//Тука вадя паролата
	
$passbytes = bin2hex(openssl_random_pseudo_bytes(64)); 
                $dataPass = hash('sha256',$passbytes. $dataPass);
               
                if ($dataPass != $sql['pass']) {
                    return 'wrong_pass';
                }
 
Няма да стане така защото openssl_random_pseudo_bytes() вади рандом стринг. Сигурно нещо с foreach трябва.
 
teroristd каза:
Няма да стане така защото openssl_random_pseudo_bytes() вади рандом стринг. Сигурно нещо с foreach трябва.
Оооо не не твърде сложно го правиш. Не е толкова нужно това виш как:


Код:
$pass = hash( 'sha256','string'.$dataPass );

Код:
public function start($dataEmail, $dataPass) {

        if (empty($dataEmail) || empty($dataPass)) {
            return 'empty_fields';
        }

        $this->prepare('USE db1')->execute();


        if ($sql = $this->prepare('SELECT * FROM login WHERE email=?', array($dataEmail))->execute()->fetchAllAssoc()) {
            
                //Тука вадя паролата
                $dataPass2 = hash('sha256','string'. $dataPass);
                
                if ($dataPass2 != $sql['pass']) {
                    return 'wrong_pass';
                }
            
            return 'ok';
        }
        return 'wrong_email';
}
 
Всеки потребител има различна парола. Дори само md5('string'.123456) да използваш това просто е неразпознаваемо спрямо паролата 12456 когато имаш този стрингов ключ.
 
Не си прав за това. Дори някой не много сериозен хакер може да разбие паролата и ще ти кажа как. Ще се регистрира с най простата парола например 123456 и ще получи стринга заедно със солта. После ще почне да добавя различни стрингове само сол. Ще ги хешва и ще ги съпоставя със стринга който, вече има докато не получи съвпадение. И има програми които ще ти го направят автоматично. Да не говориме че има таблици със милиони готови хешове със и без сол. Също така изчислителната мощ на компютрите се е увеличила много и такива операции дори няма да му отнемат много време. Отделно това е най простия вариант, има и други начини за разбиване на хеширането, и то не малко. Разбивани са много-по сложни алгоритми за хеширане от md5. Аз или ти няма да можеме ама има много по умни хора от нас.
 
teroristd каза:
Не си прав за това. Дори някой не много сериозен хакер може да разбие паролата и ще ти кажа как. Ще се регистрира с най простата парола например 123456 и ще получи стринга заедно със солта. После ще почне да добавя различни стрингове само сол. Ще ги хешва и ще ги съпоставя със стринга който, вече има докато не получи съвпадение. И има програми които ще ти го направят автоматично. Да не говориме че има таблици със милиони готови хешове със и без сол. Също така изчислителната мощ на компютрите се е увеличила много и такива операции дори няма да му отнемат много време. Отделно това е най простия вариант, има и други начини за разбиване на хеширането, и то не малко. Разбивани са много-по сложни алгоритми за хеширане от md5. Аз или ти няма да можеме ама има много по умни хора от нас.
Честно казано едно е бруте форс атака и съвсем друго е разбиване на хеша. Не бъркай нещата. Никой няма да тръгне да издирва алгоритъма ти за криптиране на паролата. Първо дори да се регистрира с парола 12456 и друг потребител има същата парола то мога да ти кажа, че не е нужно да ти разбие базата за да познае на някой абонат хешираният вид на паролата му. Просто ще си адне спама към логина и ще върти паролите които има. Реално ако някой ти разбие базата и достигне до таблиците и информацията в тях то повярвай ми вероятно ще има паролата и на ftp то ти за да се логне и да види как хешираш. Дори да адваш рандом стринг към паролата при въвеждането и в базата ти този стринг трябва да го пазиш отново в базата и да го викаш за да можеш да си правиш сравнението иначе няма да ти е вярно. Реално ти трябва лека магарийка със стрингов ключ и това ти е решението. Прекалено трудно става разпознаването на хеша. Той ще трябва да генерира 2000 пароли през формата ти което е глупаво. Прави си го както знаеш но md5(hash('stringKey'.$pass)); и повече от това не ти е нужно. Повярвай ми не трябва да ти достигат до базата достигнат ли лесно могат да разберат алгоритъма ти за хеширане а пък и честно казано едвали ще им е наложащо да го правят. :)
 

Back
Горе