Prodej projektu Duchod.cz - SLEVA
Stránka 1 z 2 12 PosledníPoslední
Zobrazují se odpovědi 1 až 30 z 41

Hash sha512 nevěděl by někdo?

  1. Ahoj všichni,

    nevěděl byste někdo jak správně vyhashovat heslo pro přístup do administrace ?

    Je tam tahle funkce:

    Kód:
    public static function encrypt_password($email, $password) {
    		$email = hash('sha512', $email);
    		$hash	 = hash('sha512', $password . $email);
    
    	for($i = 1;$i <= 1000;$i++) {
    			$hash = hash('sha512', $hash);
    		}
        	
    	return $hash;
      
      
    	}
    
    	public static function login($email, $password) {
    		$result = Db::queryOne('SELECT `user_id` FROM `users` WHERE `email` = ? AND `password` = ?', array($email,$password));
    		return (!is_null(@$result->user_id)) ? @$result->user_id : false;
    	}
    Zkouším na to přijít ve zkoušečce:

    PHPTESTER - Test PHP code online

    Generuji toto, ale heslo to potom nebere...:

    Kód:
    <?php
    
    $email = "admin@ulovzakaznika.cz";
    $password = "noveheslo";
    
    
    	$email = hash('sha512', $email);
        $hash	 = hash('sha512', $password . $email);
    
    	for($i = 1;$i <= 1000;$i++) {
    			$hash = hash('sha512', $hash);
    		}
    
    
        	
    	echo $hash;
    Předem dík za rady.

  2. Co se právě děje na Webtrhu?
    Tommy85 poptává: PrestaShop 1.4.6.2 úprava eshopu
    StudioFly poptává: Coin flip pre hru rust (steam api)
    BePositive s.r.o. poptává: PHP / Nette - výpomoc na projektu
  3. důrazně doporučuji přejít na funkce http://php.net/manual/en/function.password-hash.php, současný stav je naprosto nedostatečný a vysoce nebezpečný. Použití sha512 pro takhle krátký vstup je naopak kontraproduktivní, protože se používají 64 bitová slova a výrazně s tím usnadňuješ práci útočníkovi, to jen tak mimochodem.

    Kód vypadá stejně, pohlídal bych velikost písmen v emailu. Obecně není vůbec vhodná dávat email do samotného hesla, best practise je zvolit sůl unikátní pro každé heslo, naštěstí password_hash tohle dělá správně a není potřeba to řešit, projdi si odkázaný manuál a doporučiji přeuložit všechna hesla na nový formát.

  4. Takže funkci mám přepsat takto:

    Kód:
    public static function encrypt_password($email, $password) {
    		$email = password_hash($email);
    		$hash	 = password_hash($password);
    
        	
    	return $hash;
      
      
    	}

  5. Děláš to zbytečně složitý, hash z hashe nemá moc smysl, koncová hodnota není závislá na tom, jestli jsou na začátku stejný písmenka, tj. když bude znát e-mail, a bude testovat jednotlivý hesla, bude to pokaždý úplně jinej hash, takže bych to zjednodušil

    Kód:
    public static function encrypt_password($email, $password) {
            
      return hash('sha512', $email . $password);
    
    }
    Nezapomeň ale na to, že jakmile uživatel změní e-mail, musíš přegenerovat hash, proto se taky běžně hashuje jen heslo a ne e-mail.

  6. nedávej tam ten email a rozhodně nedělej hash z již existujícího hashe.

    Kód:
    public static function encrypt_password($email, $password) {
        return password_hash($password, PASSWORD_BCRYPT);
    }
    
    public static function verify_password($email, $hash) {
    return password_verify($hash, $hash)
    }
    Bcrypt již sám obsahuje sůl a ne opravdu velice nevhodné tam přídávat email, co když ho někdo změní? Mimochodem, není to encryptování, ale hashování, název té funkce je závádějící a nepřesný.

    Ještě ale vhodnější postup je nikoliv se upnout na současný algoritmus bcrypt, ale vždy používat ten výchozí i v nových verzích php, tam je potřeba ale již detektovat, jestli není heslo uložena starším algoritmem a případně po úspěšném přihlášení přeuložit hash. Vytaženo z dokumentace.

    Kód:
    if (password_verify($password, $hash)) {
        // Check if a newer hashing algorithm is available
        // or the cost has changed
        if (password_needs_rehash($hash, PASSWORD_DEFAULT, $options)) {
            // If so, create a new hash, and replace the old one
            $newHash = password_hash($password, PASSWORD_DEFAULT, $options);
            // tady přeuložit hash do db!
        }
        // Log user in
    }


    ---------- Příspěvek doplněn 03.09.2018 v 14:56 ----------

    Engineer: prosím neraď používat na hesla sha-512 bez soli, už samotný kód, který jsi napsal je z principu špatně a rozhodně by se neměl nikde vyskytovat. Je to nebezpečné si zahrávání s hesly uživatelů a jejich soukromí. Takhle uložená hesla je lahůdka hrubou silou louskat, dnes to zvládnou i notebooky.

  7. Dal jsem tam toto a nechal jsem si vypsat heslo, ten hash jsem pak uložil do databáze a stejně se nemohu přihlásit....:

    Kód:
    	
    	public static function encrypt_password($email, $password) {
    		  return password_hash($password, PASSWORD_BCRYPT);
    
    		
    	}
    Kód:
    $email = "admin@ulovzakaznika.cz";
    $password = "noveheslo";
    
    
    	 $heslo = password_hash($password, PASSWORD_BCRYPT);
    
    echo $heslo;

  8. děláš asi něco špatně, ale asi vím, kde je chyba. S funkcí password_hash již není možné porovnávat výsledný hash v sql (kvůli spoustě bezpečnostních děr v minulých dobách), ale musíš si z db načíst podle emailu hash a porovnat v php.

    Takhle by asi mohla vypadat tvoje funkce login. V tomhle případě nezapomeň do funkce password_hash dávat konstantu PASSWORD_BCRYPT, případě lze použít ten default, ale do login je potřeba ještě přidat update db, pokud se změní algoritmus.

    Tohle by již mohlo fungovat:

    Kód:
    public static function login($email, $password) {
        $result = Db::queryOne('SELECT `user_id`, `email`, `password` FROM `users` WHERE `email` = ?', array($email));
    
        if (is_null(@$result->user_id)) { return false } // user does not exists
        return password_verify($password, $result->password)
    }


    ---------- Příspěvek doplněn 03.09.2018 v 15:15 ----------

    nová php funkce password_hash totiž neobsahuje pouze hash, ale i popis algoritmu, sůl a pár dalších drobností, proto nelze přímo porovnávat v sql.

    Krom toho poslední dobou se začaly objevovat útoky, které měří čas porovnání samotného hashe a podle toho odvozují heslo, tzv. timing attack, proto již není vůbec vhodné hash porovnávat v sql, pokud na to není uzpůsobené a je potřeba to dělat bezpečně v php.

    Password_hash všechny úskalí a problémy řeší za tebe a rozhodně to je jediná správná volba v php.

  9. Dal jsem to tam takhle a hází mi to chybu: Přikládám pro jistotu celý user

    Parse error: syntax error, unexpected '}', expecting ';' in /data/web/virtuals/179602/virtual/www/domains/ulovzakaznika.cz/app/model/User.php on line 24

    Kód:
    class User {
    
    	public $user_id;
    
    
    	public function __construct($user_id) {
    
    		$this->user_id = $_COOKIE["user_id"];
    		$user = Db::queryOne('SELECT * FROM `users` WHERE `user_id` = ?', array($this->user_id));
    
    	}
    	
      public static function encrypt_password($email, $password) {
    		  return password_hash($password, PASSWORD_BCRYPT);
    
    		
    	}
    
    public static function login($email, $password) {
    $result = Db::queryOne('SELECT `user_id`, `email`, `password` FROM `users` WHERE `email` = ?', array($email));
    
    if (is_null(@$result->user_id)) { return false }; // user does not exists
    return password_verify($password, $result->password);
    }
    
    
    	public static function logged_in() { 
    		if(isset($_SESSION["user_id"]) OR isset($_COOKIE["user_id"])) {
    			return true;
    		} else return false;
    	}
    
    	public static function logged_in_redirect() { 
    		if(User::logged_in()) {
    			Controller::redirect('');
    		}
    	}
    
    	public static function logout() {
    
    		session_destroy();
    
    		if(isset($_SESSION["user_id"])) {
    			unset($_SESSION["user_id"]);
    		}
    
    		if(isset($_COOKIE['user_id'])) {
    			unset($_COOKIE['user_id']);
    			setcookie("user_id", "", time()-3600,"/");
    		}	
    
    		Controller::redirect('');
    	}
    
    	public static function get_type($user_id) {
    		$result = Db::queryOne('SELECT `type` FROM `users` WHERE `user_id` = ?', array($user_id));
    		return $result->type;
    	}
    
    	public static function check_permission($level = 1) {
    
    		if(!User::logged_in() || User::get_type($_COOKIE["user_id"]) < $level) {
    			$_SESSION['error'][] = 'Prosím přihlaste se pro přístup ke stránce.';
    
    			Controller::redirect('');
    		}
    	}
    
    	public static function is_admin($user_id) {
    		return (User::get_type($user_id) > 0) ? true : false;
    	}
    
    	public static function get_back($new_page = "index") {
    		if(isset($_SERVER['HTTP_REFERER']))
    			Header('Location: ' . $_SERVER['HTTP_REFERER']);
    		else
    			Kontroler::presmeruj($new_page);
    		die();
    	}
    }

  10. :TomášX Salt musíš taky někam uložit, pokud se dostane někdo až sem, tak bude mít k dispozici celý kód aplikace i salty. I kdybys je vytvářel dynamicky z nějakých permanentních dat, tak si to dotyčný z kódu PHP zjistí.

    :Petr Jasně, že ti to nefunguje, protože když to zavoláš takhle, tak si to pokaždý vygeneruje novej salt, takže konečnej hash je pokaždý jinej, si to zkus:
    Kód:
    <?php
    print password_hash('heslo', PASSWORD_BCRYPT) . PHP_EOL;
    print password_hash('heslo', PASSWORD_BCRYPT);
    ?>

  11. v tom mém kódu za returny mi chybí ;

    Promiň, píšu to jen na mobilu a php nemám v ruce, není to můj primární jazyk

    ---------- Příspěvek doplněn 03.09.2018 v 15:32 ----------

    engineer: jak píšeš sám, password_hash ukládá salt jako součást hashe, není ho potřeba nikam ukládat. Salt nemá smysl pokud je globální, vygenerovat pro něj rainbow table je otázka pár hodin a 100gb dat.

    password_hash s bcryptem v současné verzi php je navržený tak, že znalost kódu, saltu a hashe nevede k vyzrazení původního hesla a odolnost proti útoku hrubou silou je vysoká. Parametrem cost jí lze ještě zvednout, mám-li k tomu potřebu.

    Doporučovat na ukládání hesel sha-512 je opravdu hodně nebezpečné a nerozvážné.

  12. Co s tim, aby to bylo stejné ?

  13. nikdy to nebude stejné, to je úmysl. Od toho existuje password_verify, kód který jsem ti tady napsal bude fungovat, jen oprav ty středníky, s tím si snad již poradíš.

    Na odkazovaném manuálu to popisují, napravo pak máš odkaz na funkci password verify, také s popisem.

    Ten kód jsem bral z dokumentace.

  14. Vygeneroval jsem noveheslo: Takže mi to vybralo náhodné...

    print password_hash('noveheslo', PASSWORD_BCRYPT);

    A pak jsem ho vložil do databáze do password....

    A nic... nedostanu se tam.

  15. Jj, to je moje chyba, myslel jsem si, že to porovnáváš jako řetězec, blbě jsem si přečetl kód.

    Nebudu se tady dál hádat offtopic, jaký má smysl salt v hacknuté DB, to, co jsem uvedl jako funkci nahoře je jednoduchá fce, která ti pokaždý vrátí stejný hash, tj. když jí zavoláš, tak můžeš pak porovnat hash v DB a hash aktuální.

  16. tenhle kód funguje, můžeš si ho přímo vyzkoušet na http://phptester.net

    PHP kód:
    <?php
    echo "<pre>";

    function 
    encrypt_password($email$password) {
        return 
    password_hash($passwordPASSWORD_BCRYPT);
    }


    $email "admin@ulovzakaznika.cz";
    $password "noveheslo";


    $hash_v_db encrypt_password($email$password);
    echo 
    "heslo v db\n";
    var_dump($hash_v_db);

    // login
    echo "\nověření přihlášení\n";
    var_dump(password_verify($password$hash_v_db));
    vrací to

    Kód:
    heslo v db
    string(60) "$2y$10$bUHX2NECe2l2NG/BWQqpveB3O49EMIcqX0HXskm89PlhrhzAAkxwG"
    
    ověření přihlášení
    bool(true)
    Co děláš jinak? Jak já je velikost pole pro password v db? Měla by být alespoň 64 znaků. Musíš také upravit tu funkci login, aby nekontrolovala hash v db, ale načetla ho a pak si ho zkontroluješ u sebe. Psal jsem ti tady můj návrh.


    Engineer: ta funkce, kterou jsi sem dal je nebezpečná, hrubou silou jí louskne grafika jak nic a pokud dojde k úniku hashů v db, rychle se k tomu dají zjistit hesla, to je ten problém, původní dokonce měla 1000 interakcí, což je o trochu lepší, ale pořád problém. Základní smysl saltu je zvýšit náročnost získání hesla hrubou silou přes předpočítané tzv. rainbow table, zároveň pokud dva lidé mají shodné heslo, nebudou mít shodný hash (ve spojení s emailem je to stejný efekt, ale to zanáší jiné komplikace a problémy). Pokud je salt v db a pro každé heslo jiný, útočník musí hrubou silou louskat všechny kombinace pro každé heslo, nemůže si práci nijak ulehčit (pokud by byl salt pouze jednou v kódu, stačí mu lousknout jedno heslo a zbytek má již snadnější). Password_hash používá bcrypt, což je v současnosti nejpokročilejší algoritmus pro ukládání hesel, interně používá tisíce interakcí při hashování. Zároveň používá normalizovaný tvar hashe, který umožňuje snadno v budoucnu přejít na novější algoritmus a přímo uložit hash. Pro zvýšení odolnosti hesla např. heslo rozmnožuje až na 64 znaků, aby útočník nemohl použít některé optimalizace v závislosti na délce hesla. Nemá smysl vymýšlet vlastní řešení pokud k tomu nemám dostatečné znalosti, tyhle funkce prošly auditem, jsou pod kontrolou, tvoje funkce je plácnutí do vody bez formální a faktické verifikace.

  17. V tom kodu mám jenom tohle... nedaří se mi přihlásit v databázi má heslo varchar 2000

    Kód:
    class User {
    
    	public $user_id;
    
    
    	public function __construct($user_id) {
    
    		$this->user_id = $_COOKIE["user_id"];
    		$user = Db::queryOne('SELECT * FROM `users` WHERE `user_id` = ?', array($this->user_id));
    
    	}
    	
      public static function encrypt_password($email, $password) {
    		  return password_hash($password, PASSWORD_BCRYPT);
    
    		
    	}
    
    public static function login($email, $password) {
    $result = Db::queryOne('SELECT `user_id`, `email`, `password` FROM `users` WHERE `email` = ?', array($email));
    
    if (is_null(@$result->user_id)) { return false; }; // user does not exists
    return password_verify($password, $result->password);
    }
    
    
    	public static function logged_in() { 
    		if(isset($_SESSION["user_id"]) OR isset($_COOKIE["user_id"])) {
    			return true;
    		} else return false;
    	}
    
    	public static function logged_in_redirect() { 
    		if(User::logged_in()) {
    			Controller::redirect('');
    		}
    	}
    
    	public static function logout() {
    
    		session_destroy();
    
    		if(isset($_SESSION["user_id"])) {
    			unset($_SESSION["user_id"]);
    		}
    
    		if(isset($_COOKIE['user_id'])) {
    			unset($_COOKIE['user_id']);
    			setcookie("user_id", "", time()-3600,"/");
    		}	
    
    		Controller::redirect('');
    	}
    
    	public static function get_type($user_id) {
    		$result = Db::queryOne('SELECT `type` FROM `users` WHERE `user_id` = ?', array($user_id));
    		return $result->type;
    	}
    
    	public static function check_permission($level = 1) {
    
    		if(!User::logged_in() || User::get_type($_COOKIE["user_id"]) < $level) {
    			$_SESSION['error'][] = 'Prosím přihlaste se pro přístup ke stránce.';
    
    			Controller::redirect('');
    		}
    	}
    
    	public static function is_admin($user_id) {
    		return (User::get_type($user_id) > 0) ? true : false;
    	}
    
    	public static function get_back($new_page = "index") {
    		if(isset($_SERVER['HTTP_REFERER']))
    			Header('Location: ' . $_SERVER['HTTP_REFERER']);
    		else
    			Kontroler::presmeruj($new_page);
    		die();
    	}
    }

  18. hm, to vypadá dobře.

    Dokážeš sem dát nějaké debug hlášky? Zajímalo by mě:

    1. co obsahuje $result ve funkci login()
    2. jakou mají hodnotu proměnné $email, $password (u hesla stačí, když řekneš, že obsahuje správné heslo)
    3. zkus odstranit celý řádek s if (is_null(@$result->user_id)) ve funkci login(), podle ostatního kódu tam být nemusí a neselže to ani když email neexistuje

  19. V $result je dotaz do databáze....je tam vyber všechno a porovnej emaily....

    hodnotu proměnné by to mělo mít admin@ulovzakaznika.cz a heslo noveheslo..uložené šifrou do databáze...

    Jak ti mám nechat vypsat to co to udělá po tom..co to odešlu ?

  20. použij var_dump() a odstraň z kódu redirect nebo to zapiš do databáze. Vidím co to má obsahovat, zajímají mě hodnoty, dal jsem ti sem samostatný kód, který sám o sobě funguje, v tvém kódu nevidím na první pohled chybu, tak mě zajímá, jestli se to z db načte v pořádku a jestli to tam je správně uložené. Toť vše.

  21. Dal jsem to vypsat nad class user v user.php...A ukazuje mi to toto:

    Kód:
    Notice: Undefined variable: result in /data/web/virtuals/179602/virtual/www/domains/ulovzakaznika.cz/app/model/User.php on line 3
    NULL

  22. očividně jsi to tam dal špatně :). Je tam potřeba zavolat celé tělo funkce a ne jen výpis result, který se inicializuje až v samotné funkci.

  23. A jak to tam mám dát teď to zase hledá email, že neni nadefinován.... jak zavolat ve var dump dvě funkce ? Tu na ten password a tu a login?

    Kód:
     $result = Db::queryOne('SELECT `user_id`, `email`, `password` FROM `users` WHERE `email` = ?', array($email));
    
    if (is_null(@$result->user_id)) { return false; }; // user does not exists
    return password_verify($password, $result->password);
    
    echo var_dump($result);

  24. tak to dej do té funkce login a nevytahuj to ven :).

  25. Takhle? to je asi blbost..píše to undefined constant a varchar 5

    echo var_dump(login);

  26. tohle se složitě dělá, když neumíš dobře programovat :)

    takhle nějak

    PHP kód:
    public static function login($email$password) {
    $result Db::queryOne('SELECT `user_id`, `email`, `password` FROM `users` WHERE `email` = ?', array($email));
    var_dump($result);
    var_dump($result->password);
    var_dump($password); //nech jen pokud není tajné, ale testovací
    var_dump(password_verify($password$result->password));
    exit(); 
    //ať se nesnaží nic jiného vypisovat, přesměrovávat a nechá tam debug výstupy
    return password_verify($password$result->password);


  27. Kód:
    object(stdClass)#5 (3) { ["user_id"]=> int(1) ["email"]=> string(22) "admin@ulovzakaznika.cz" ["password"]=> string(129) "03f58636d0806dacf67dbe77c4efbb8091a842ef3512240aa859a14a96478987916be12f2777c8bb1ef4dc1b0d4acf032fc9445144a2a04c1de769eff9a87d7c " } string(129) "03f58636d0806dacf67dbe77c4efbb8091a842ef3512240aa859a14a96478987916be12f2777c8bb1ef4dc1b0d4acf032fc9445144a2a04c1de769eff9a87d7c " string(60) "$2y$10$SUl9CXPHHVkmJBGTqa/tReeq7F21P4DaALrxqmqCQ/PdkjCeL7mZ2" bool(false)

  28. už to vidím:

    1. v db máš uložen starý formát hashe, pokud použiješ password_hash musíš hesla přeuložit. Jedná se o nový nebo existující projekt?
    2. jako parametr funkce login() dáváš do proměnné password nový hash, má tam být původní heslo, který uživatel zadal z formuláře a nikoliv nějaká předzpracovaná věc

    Zároveň k tvému úvodnímu příspěvku, důvod proč jsi tohle začal řešit je nejspíš to, že ti nešlo se přihlašovat. Na výpisu lze vidět, že v db máš hash hesla s mezerou na konci, poté při pornávání (viz tvůj úvodní příspěvek) to nesouhlasí a proto ti nefungovalo přihlášení. Pokud bys to v db opravil, nejspíš ti tvůj původní kód bude fungovat.

  29. Nechal jsem v databázi jen jeden účet s jedním heslem..vygenerovaným přes password hash...

    Je to starý projekt..mám jen zpřístupnit administraci.... potřebuji dát ten vygenerovaný hash do databáze a mělo by to chodit, ale nechodí.... vrátil jsem tvůj původní kod.

    Kód:
    object(stdClass)#5 (3) { ["user_id"]=> int(3) ["email"]=> string(22) "admin@ulovzakaznika.cz" ["password"]=> string(60) "$2y$10$ilzKn/lSi99fkI02mjOQheqF/HQUJ8IsnXasn0fNUHBMtBMZmrV2W" } string(60) "$2y$10$ilzKn/lSi99fkI02mjOQheqF/HQUJ8IsnXasn0fNUHBMtBMZmrV2W" string(60) "$2y$10$37OSa.Ze2im4JU0vaiAMhuLvTX0H5ZBiuggJ9p19BgoHfhOf/QrOu" bool(false)

  30. to už vypadá lépe. Teď ještě vyřešit bod (2), do funkce login jako argument dáváš email a password, email má správnou hodnotu a načte se z db, ale jako password tam předáváš hash, mělo by tam být heslo, které jde z formuláře. V kódu třídy User, kterou jsi sem dával žádné volání tenhle funkce není, musí to tedy být ještě někde jinde, nejspíš se heslo z formuláře nejprve prožene funkci encrypt_password a poté se pošle do loginu, hledej, kde jinde se tahle funkce používá a najdeš místo, které upravit, aby login dostal heslo a ne hash.

  31. Ten web je docela malej..je tam jenom controller , model a view ve složce app......

    Co tohle ?

    Kód:
    <?php
    // Controller pro hlavní stránku
    
    class AdminController extends Controller
    {
    	public $admin = 1;
    	
        public function process($parameters)
        {
    
    		$this->header = array(
    				'title' => 'Administrace - Ulov zákazníka',
    				'keywords' => '',
    				'description' => '',
    		);
    
    		if(!User::logged_in()) {		
    		
    			if (!empty($_POST) AND isset($_POST['submit'])) {
    				$_POST['email'] = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
    				$_POST['password'] = User::encrypt_password($_POST['email'], $_POST['password']);
    
    				if (empty($_POST['email']) || empty($_POST['password'])) {
    					$_SESSION['error'][] = 'Musíte vyplnit e-mail a heslo.';
    				} elseif (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) == false) {
    					$_SESSION['error'][] = 'Zadaný e-mail nemá platný formát.';
    				} elseif (User::login($_POST['email'], $_POST['password']) == false) {
    					$_SESSION['error'][] = 'Neplatné přihlašovací údaje.';
    				}
    
    				if (!empty($_POST) && empty($_SESSION['error'])) {
    					$login = User::login($_POST['email'], $_POST['password']);
    
    					setcookie("user_id", $login, time()+60*60*24*30,"/");
    
    					$_SESSION['user_id'] = $login;
    					
    					$this->redirect('admin');
    				}
    
    			}
    
    			$this->view = 'admin/login';
    
    		} else {
    			$this->view = 'admin/index';
    		}
        }
    }

Stránka 1 z 2 12 PosledníPoslední
Hostujeme u Server powered by TELE3