Autor Zpráva
montly
Profil *
Čau,

dělám přihlašování registrovaných uživatelé a setkal jsem se tady s takovým, mno asi problémem, proto se radši zeptám:

kontroluju jestli přezdívka a heslo se shodují v databázi...

$prezdivka = $_POST['prezdivka'];
$heslo = $_POST['heslo'];

$vyber = "SELECET id, prezdivka from uzivatele WHERE prezdivka = '".$prezdivka."' AND heslo = '".$heslo."'";
$query = mysql_query($vyber);

...teď kontroluju jestli se vrátí true

if ($query) { ...

ale tady podmínka je splněná i když prezdivka a heslo se neshodují v databázi, čím to je?

musím použít mysql_num_rows

díky
Str4wberry
Profil
„ale tady podmínka je splněná i když prezdivka a heslo se neshodují v databázi, čím to je?“
Zkusím to zjednodušit:
SQL dotaz proběhl v pořádku. Jestli ten výběr vrátil nějaké řádky „není jeho starost“.
montly
Profil *
ale jak může SQL dotaz proběhnout v pořádku i když zadám jak login i heslo co se v databázi nenechází?
Alphard
Profil
dotaz vrátí nalezené záznamy, pokud podmínkám nevyhovuje žádný, tak nevrátí žádný, ale ani chybu
v tvém případě zkontroluj počet řádků pomocí mysql_num_rows()
montly
Profil *
myslel jsem že vrací false, pokud nic nenajde, díky
parm
Profil *
ten dotaz SELECET je tam vporadku? nemelo by tam byt SELECT?
montly
Profil *
SELECT je správně, tam to je překlep
shadyyx
Profil
a btw, je dobre (bezpecne) hesla v DB hashovat(cryptovat) - jestli pouzitim SHA nebo MD5 si muzes zvolit sam (nebo jeste ma php funkce jako mcrypt apod), ja treba pouzivam md5(); - pri registraci se (po validaci $heslo1==$heslo2) do DB inputuje md5($heslo1) a pri prihlasovani se porovnava md5($heslo_pri_prihlaseni)==$heslo_z_DB ... skript je o neco slozitejsi, nicmene je vse o neco bezpecnejsi...
Tomáš Hanus
Profil
shadyyx
+jeste se pouziva vlozeni do hesla nahodne vygenerovana posloupnost znaku

EDIT: říká se tomu "salted hash"
Už je pozdní hodina ;)
Alphard
Profil
Tomáš Hanus
asi myslíš salted hash, ale formulace vlozeni do hesla nahodne vygenerovana posloupnost znaku mi přijde nešťastná, evokuje představu ruské rulety při přihlašování
shadyyx
Profil
mno dost si to neumim predstavit, zrejme reakce Alpharda byla na miste...
mam ted nejakou praci takze se mi nechce googlit, co to je, ale jak dokoncim podivam se na to, zni to zajimave ;-)
Alphard
Profil
shadyyx
jen jsem upozornil na nejednoznačnost formulce
posloupnost znaků je náhodná, to ano, ale myslím, že je nutné zdůraznit, že se pouze náhodně zvolí, pak je vždy stejná

tedy např. md5 ($_POST['heslo']."sul_sul_sul"); ale v žádném případě md5 ($_POST['heslo'].rand (1,10));

jinak vyhledávače na salted hash určitě uslyší (dík djlj)
shadyyx
Profil
fuuu, tak co jsem ted nasel je fakt HUSTEEEEE!!!!

string se nejdriv md5(), prida se salt, a potom se to cely jeste sha1() TY KOKSO!!! tomu uz rikam "popici" cryptovane heslo!!!

EDIT: vsechno hezky, akorat pak budu muset nekde jeste ukladat a uchovavat (DB) jeste i samotny salt...ale je to husty...
djlj
Profil
shadyyx
Tý jo, vážně hustý a hafo kůl.

Alphard
uslyší

Ono je to stejně celkem jedno, kolikrát to zahashuješ (jak se to sakra dá napsat česky?), protože když se ti někdo dostane do databáze, tak už mu bude fuk, jaký hesla uživatelé maj :).
shadyyx
Profil
djlj
ano, v podstate mas pravdu, jen si je treba uvedomit, ze jsou ruzne typy utoku a ruzne typy hackru...budto muze jit jen o zaskodnika, ktery ti to smaze, prepise, nebo neco podobnyho, nebo muze jit o nekoho, kdo se chtel dostat nekam dal (treba prave pres pristupovy heslo admina nebo nejakeho uzivatele) - no kdyz mas hesla hashovany(cryptovany) alespon jednou, minimalne mu tim docela zkomplikujes zivot...

(ale to je uz stejne offtopic asi poslednich 10 prispevku, jenomze koho to sere kdyz autor prispevku uz vyresil svuj problem a vice se tu neukazuje??? :-D :-P )
montly
Profil *
kdyz autor prispevku uz vyresil svuj problem a vice se tu neukazuje???

ukazuje, pořád se diví, že jeho téma je na vrcholu dotazů, pročítám si to každej den

kdo se chtel dostat nekam dal (treba prave pres pristupovy heslo admina nebo nejakeho uzivatele)

je zbytečný mít nějaký speciální právo pro admina, když chci něco udělat, udělám to v rámci serveru ne přes web. A pokud ti získá heslo dejme tomu správe/admina tak bude mít jen klasický práva jako mazání, editování ... což není problém, pokud se řádně zálohujou data.
Aleš Janda
Profil
Alphard
tedy např. md5 ($_POST['heslo']."sul_sul_sul")

Spíš bych udělal něco jako md5 ($_POST['heslo']."sul_sul_sul".$id_uzivatele). Ovšem to id_uzivatele se pak přirozeně nesmí nikdy změnit ;-)
Tím to se zajistí to, že případný útočník by nezjistil, že mají dva uživatelé stejná hesla.
shadyyx
Profil
Ales Janda
zadni dva uzivatele nebudou mit stejna hesla (nebo tato pravdepodobnost je mizerne malinkata) - protoze ke kazdymu heslu se pridava prave ruzne generovana "sul" - takze treba i kdyby si dva uzivatele zvolili to same heslo, ktere po md5() treba ma stejny tvar, pridava se ke kazdymu jina "sul" (nahodne generovana predtim - ta se muze taky hashovat)...

Priznejme si ale, kdy ma takoveto zabezpeceni sve misto??? pro obycejne fora, diskuzni knihy, drobne aplikace??? Kdybych delal nejakou aplikaci kde se prevadi spousta penez, nebo aplikaci pro narodni bezpecnostni urad, tak bych jiste zapatral po co nejlepsim zabezpeceni hesel ;-)
Aleš Janda
Profil
shadyyx
Myslel jsem, že tím md5($_POST['heslo']."sul_sul_sul") je myšlena nějaká statická (pořád stejná) sůl. Pokud se generuje vždy nová a ukládá do DB společně s heslem, je to ok.

Sůl už se ale v DB hashovat nemůže, protože by pak heslo nešlo zpětně ověřit ;-)
shadyyx
Profil
Ales Janda
jakze ne??? mas heslo, ktere po registraci hashnes, pridas zahashovanou sul a vlozis do DB hash(heslo).hash(sul) do tabulky heslo a sul do tabulky sul... vypadat by to mohlo podobne:
$hashed_pw = hash($_POST["heslo"]).hash($sul);
mysql_query("INSERT INTO tabulka(heslo, sul) VALUES('$hashed_pw', '$sul') WHERE user_id = '$user_id'");
//moc zjednodusene

a pak pri prihlasovani se udela asi todleto:
$sul = mysql_result(mysql_query("SELECT sul FROM tabulka WHERE username = '".$_POST["nickname"]."'"),0);
$pwd = hash($_POST["heslo"].hash($sul);
mysql_query("SELECT username, heslo, sul FROM tabulka WHERE username = '".$_POST["nickname"]."' AND heslo = '$pwd'");


nezarucuju ze je to regulerni, nebo ze by to fungovalo, nebo ze je to docela idealni, jenom chci dementovat, ze to prece jde ;-)
BetaCam
Profil
1. Pokud se někdo dostane přímo do DB je veškeré hashování k ničemu.
a) Admin hash si mohu s trochou štěstí a intuice vygenerovat kdekoliv jinde a vložit si ho do DB k administrátorskému accountu. ( Zbytečnost je to okaté, protože skutečnej admin se poté nebude moct přihlásit se svím heslem)
b) Ve většině případů si mohu udělat Admin účet z libovolného uživatelského účtu. ( Zbytečnost opět je to okaté, protože pak bude účet veden jako admin a na 99,99% si toho všimne skutečný admin, že admin práva má někdo kdo by je neměl mít )
c) Pokud mám přímí přístup do DB je zbytečné zjištovat heslo admina či vytvářet si admin účet, protože bych te tím zbytečně omezoval.
d) Administrátor ( admin účet ) je omezen hlavně možnostmi své aplikace a jejími funkcemi.
e) S přímím přístupem do DB si mohu dělat "co chci" nejsem omezen nasazenou aplikací narozdíl od přístupu přes admin účet.

2.
a) Hash hesla se hodí pokud někdo donutí aplikaci vypsat z DB sloupec s heslem ( Nemá heslo jak na talíři, ale musí hledat kolize )
b) další věc je ta, že ani samotný správce aplikace ( serveru ) by neměl znát skutečná hesla běžných uživatelů a to hlavně proto, že většina lidí dnes používá jedno jméno a například 2 - 3 hesla k většině přístupů. Každý zodpovědný admin by měl ctít soukromí uživatele a heslo opravdu soukromá věc je!
c) Každý by si měl uvědomit, že ukládání nehashováného hesla nemusí znamenat "zkázu" jenom vlastní aplikace, ale i "zkázu" aplikace třetích osob. ( viz. bod a + b )

For shadyyx:

jakze ne??? mas heslo, ktere po registraci hashnes, pridas zahashovanou sul a vlozis do DB hash(heslo).hash(sul) do tabulky heslo a sul do tabulky sul... vypadat by to mohlo podobne:

Tuhle myšlenku sem opravdu moc nepobral, ale třeba sem to jen špatně pochopil. Pokud mi to vysvětlíš budu velice rád, ale zatím na to mám tento názor:

Celá tato myšlenka mi přijde jako nesmysl z několika důvodů:
1. do DB ukládáš hash(pass).hash(salt) čož beru, ale dále ukládáš samotný string SALT v nehashované podobě čímž dáváš za pravdu vetě :
Sůl už se ale v DB hashovat nemůže
Hashuješ SALT v aplikaci, ale v DB ji máš v čisté podobě. Efekt je tedy podle mě téměř ZERO.

2. pokud by si do DB uložil hash(salt) stane se samotný HASH novím stringem SALT a původní string SALT použitý pro hashování tím postrádá funkci a už není hodnotou SALT. Salt do DB nemůžeš uložit hashovanou, protože poté se samotný HASH stane SALTem. SALT můžeš do DB uložit zašifrovaný, ale né zahashovaný.

Pokud na to máš jiný názor budu rád když mi to vysvětlíš.
BetaCam
Profil
Ještě dodatek pro shadyyx:

$hashed_pw = hash($_POST["heslo"]).hash($sul);
mysql_query("INSERT INTO tabulka(heslo, sul) VALUES('$hashed_pw', '$sul') WHERE user_id = '$user_id'");


nejsem si zcela jistej jestli chápeš dobre Salted hash, protože z techto řádek co si napsal mi to tak neprijde, ale treba to je jen překlep.

$hashed_pw = hash($_POST["heslo"]).hash($sul); // toto je krásná věc bohužel nesplnuje definici Salted hash

Salted hash má primárně zamezit tomu, aby bylo poznat, že mají dva uživatelé stejné heslo. Což, ale tvůj kód v podstatě nesplnuje. Lépe řečeno tak jak to máš napsané ty je tam SALT uplně k ničemu. Příklad :

$pwd = sha1($_POST['pass']).sha1($salt);

pokud to takhle použiješ při ověrení hesla je tam sha1($salt) úplně na nic.

1) sha1($salt) bude vždy správně protože salt beru z DB nic méně to je v celku jasné
2) pokud do DB uložím $hashed_pw = sha1($_POST['pass']).sha1($salt); jako heslo tak sem tím vůbec ničeho nedosáhnul, protože sha1($_POST['pass']) = 40 znaků a sha1($salt) = 40 znaků pokud bude mít heslo v DB 80 znaků řekl bych, že 99% lidí napadne vytisknout si hodnotu sha1($salt) a krásně uvidí, že má brát v úvahu jen prvních 40 znaků, protože to je hash Hesla. Od této chvíle tedy ví, že ti uživatelé kterí mají schodních prvních 40 znaků mají stejné heslo. takže jediného čeho si dosáhl je zbytečných 40 znaků v DB u každého uživatele.

Proto by se hash hesla měl skládat například takto :

$pwd = sha1($_POST['pass'].$salt);

když ho uložíš do DB takhle bude mít hash vždy 40 znaků, ale každé (stejné) heslo ho bude mít jiný. To kam si salt dáš už je na tobě, ale logicky neni vhodné ho dávat na začátek a konec hesla.

A jestli si měl v tom tvém kódu jen překlepy tak promiň za knihu na pokračování :)
shadyyx
Profil
"RISPA"

nerozumim tomu docela ani ted...zajimalo by me, kdyz generujes salt (pac musi byt pro kazdyho uzivatele jiny) jak si ten salt pak uchovas???jak pak vis ze k tomu heslu ma byt tento hash???

a tech 40 znaku navic nemusi byt pravda, ten kod byl dost bagatelizovan a zjednodusen, ale z hash(salt) by se udelal substring(hash(salt),0,NEJAKA_DELKA) a uz je to reba jen 10 znaku...

ale opravdu me zajima kam ten salt pro kazdeho uzivatele ulozis???
BetaCam
Profil
No do databáze přímo do sloupce vedle hesla.
BetaCam
Profil
shadyyx

a tech 40 znaku navic nemusi byt pravda, ten kod byl dost bagatelizovan a zjednodusen, ale z hash(salt) by se udelal substring(hash(salt),0,NEJAKA_DELKA) a uz je to reba jen 10 znaku...

No ale to na věci nic nemění je jedno jestli salt bude mít 10 nebo 2000 znaků. Pokud by si to do DB ukládal tak jako ty bude celkem jasne vyditelné, kterí uživatelé mají stejné heslo.
shadyyx
Profil
BetaCam

takze jak bys to udelal ty??? myslim od vlozeni do DB po kontrolu pri prihlasovani???
BetaCam
Profil
No to záleží na tobě :)

Nejjednodušeji to lze udělat třeba takhle jak popisuje Jakub Vrána :

http://php.vrana.cz/ukladani-hesel.php

tedy nějak takto :

mysql_query("SELECT * FROM uzivatele WHERE login = '$_POST[login]' AND heslo_sha1 = SHA1(CONCAT('$_POST[heslo]', salt))");

Trochu komplikovanější řešení je vytáhnout si z DB salt a password do aplikace a vložené heslo spojit se SALTem trochu komplikovanějším způsobem než jen přidáním SALTu za heslo. Třeba polovinu SALTu dát na začátek hesla druhou polovinu SALTu dát před poslední písmeno hesla atd. pak to prohnat přes SHA1() a následně porovnat s passwordem co byl v DB . Fantazii se meze nekladou :)
shadyyx
Profil
nic ve zlym, ale prikladem ktery jsi uvedl jsi napsal to samy co ja, jen s rozdilem, ze misto hash(heslo).substr(hash(salt),0,DELKA) je pouzita funkce CONCAT primo z mysql...

a ten samy priklad hovori o tom, ze ten salt je taky vlozen v DB a musi se pred kontrolou prihlaseni vytahnout spolu s heslem...
cili tak, jak jsi hezky zdrbal muj priklad, tak hezky jsi mu dal ted, i kdyz ne zcela primo, zapravdu...

Jedno jediny reseni, ktere uz ale neni uplne ideovo to same, je, ze kazdy uzivatel svuj salt bude znat...takze treba si zada heslo ( heslo znovu ) a pak tam bude jeste input pro nejaky dalsi retezec (treba "Vase matka za slobodna") a to se bude concatenovat s heslem...pak pri prihlasovani se bude aplikace od uzivatele vyzadovat nick, heslo, jmeno matky za slobodna, ale salt v DB vubec nemusi byt (krome podoby smichani s heslem v sloupci heslo)...jinak proste ty salty pro kazdyho uzivatele musis uchovavat v DB (pokud nejses blby a neuchovavas si je v nejakym souboru na servru...)
BetaCam
Profil
shadyyx
nic ve zlym, ale prikladem ktery jsi uvedl jsi napsal to samy co ja, jen s rozdilem, ze misto hash(heslo).substr(hash(salt),0,DELKA) je pouzita funkce CONCAT primo z mysql

Já to ve zlym neberu, ale neni to to samé :) vysvětlim níže.

a ten samy priklad hovori o tom, ze ten salt je taky vlozen v DB a musi se pred kontrolou prihlaseni vytahnout spolu s heslem...
cili tak, jak jsi hezky zdrbal muj priklad, tak hezky jsi mu dal ted, i kdyz ne zcela primo, zapravdu...


Bohužel stále nechápeš k čemu slouží SALT. SALT neni tajný může ho znát klidně i útočník a bude mu k ničemu pokud neví jak ho ty používáš.

Jedno jediny reseni, ktere uz ale neni uplne ideovo to same, je, ze kazdy uzivatel svuj salt bude znat...takze treba si zada heslo ( heslo znovu ) a pak tam bude jeste input pro nejaky dalsi retezec (treba "Vase matka za slobodna") a to se bude concatenovat s heslem...

Ano toto je možné ovšem má to háček. Budu otravovat uživatele protože v podstatě je nucen si pamatovat dvě hesla. Toto je by se dalo nazvat jako ochrana dvěmi hesly. Salted Hash je ale něco jiného.

A ted k tomu tvému příkladu:

sha1(password).substr(sha1(salt),0,10)
a
sha1(password.salt)
sou dvě rozdílné věci, mužeš si to vyskoušet na scriptu :

<?php
error_reporting(E_ALL);

$pole['0']['password'] = 'Heslo';
$pole['0']['salt'] = 'asdfghjklp';
$pole['1']['password'] = 'Heslo';
$pole['1']['salt'] = 'qwertzuiol';
$pole['2']['password'] = 'Heslo1';
$pole['2']['salt'] = 'yxcvbnmhtd';

echo 'Metoda ala <b>shadyyx</b><br />';

foreach ($pole AS $data)
{
  $hash = sha1($data['password']).substr(sha1($data['salt']),0,10);
  echo 'Hodnota password je : <b>'.$data['password'].'</b>';
  echo ' Hodnota Salt je<b> '.$data['salt'].'</b> '; 
  echo $hash.'<br />';
}
echo '<br /><br /><br />';
echo 'Metoda ala <b>Salted Hash</b><br />';
foreach ($pole AS $data)
{
  $hash = sha1($data['password'].$data['salt']);
  echo 'Hodnota password je : <b>'.$data['password'].'</b>';
  echo ' Hodnota Salt je<b> '.$data['salt'].'</b> '; 
  echo $hash.'<br />';
}
?>


tento kód vytiskne :

Metoda ala shadyyx
Hodnota password je : Heslo Hodnota Salt je asdfghjklp894f36e5fe639267301de83d341819acc0a14d4bbd45972f90
Hodnota password je : Heslo Hodnota Salt je qwertzuiol 894f36e5fe639267301de83d341819acc0a14d4be9288458d6
Hodnota password je : Heslo1 Hodnota Salt je yxcvbnmhtd d6d5d360314863ca1b9e84cda309759af3ac15effb219be3c4

Metoda ala Salted Hash
Hodnota password je : Heslo Hodnota Salt je asdfghjklp 98b5b289cf4a1a4ef1ae9eab2e951c2519824d82
Hodnota password je : Heslo Hodnota Salt je qwertzuiol d04d3d4fac155bf99ccb78e712c4ce63769d4d66
Hodnota password je : Heslo1 Hodnota Salt je yxcvbnmhtd e44458b0b11ba94971f7d70c69bc30dd83647555


a podivej se co vygeneruje tvůj postup při zadání stejného hesla. Hlavní problém hashe sem ti označil kurzívou. Doufám ze ted už hápeš v čem je rozdíl. :)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0