.... private function loginForm($content = array()) { return array( array("content", "{TITLE}", "******* vesilaitos - Netserv työnojaus kirjaudu palveluun"), array("view", "login_view.html", "{CONTENT}", "Kirjaudu")); } private function validateUser() { if(isset($_POST["user"], $_POST["pass"])) { $query = sprintf("SELECT * FROM users WHERE MD5(nimi) = '%s' AND salasana = '%s'", md5($_POST["user"]), $this->valmisteleSalasana($_POST["pass"])); $result = mysql_query($query); if(mysql_num_rows($result) == 1) { $userdata = mysql_fetch_array($result); $this->istuntoTunnus($userdata); ....
Kysymys kuuluu, voiko käyttäjänimen md5 hashauksesta olla tietoturvallista haittaa.? Miten voin tarkistaa sekä pienet että isot kirjaimet kirjautumisessa, jos en hashaa niitä ensin? Koska ilman md5() nimi sukunimi on sama kuin Nimi Sukunimi..
Mites jos ajat vertailtavat arvot strtolower()-funktion läpi ennen vertausta?
Käyttäjänimen ei koskaan pitäisi olla case-sensitive, koska se luo hämminkiä järjestelmän käyttäjille ja varmasti ylläpitäjillekin. Tiivisteiden laskeminen on suhteellisen raskasta hommaa, joten sitäkään ei pitäisi huvikseen tehdä, jos sovellus on tulossa suureen palveluun. Lisäksi tuo sinun tapasi käyttää where-ehdossa lennosta laskettavaa md5-tiivistettä on aivan järkyttävän huono idea, koska se pakottaa tietokannan käymään jok'ikisen taulun rivin läpi jokaisella kyselykerralla, mikäli MySQL ei osaa cachettaa noita.
Jos luulit case-sensitiven käyttäjänimen parantavan tietoturvaa, niin suosittelen perehtymään siihen, mitä tietoturva oikeasti on.
TeNDoLLA kirjoitti:
Mites jos ajat vertailtavat arvot strtolower()-funktion läpi ennen vertausta?
Tarkoitatko että jos k-tunnus on kannassa "Qeijo" isolla, ja käyttäjä syöttää formiin "qeijo" pienellä.. Niin minun pitäisi vertailla ne keskenään strtolower():lla jotta saisin matchin?
Mitä järkeä siinä olisi?
Syy miksi edes pähkäilen tätä, on että asiakas vaatii Mixed-case - k-tunnus ja salasana menettelyn.
The Alchemist kirjoitti:
Lisäksi tuo sinun tapasi käyttää where-ehdossa lennosta laskettavaa md5-tiivistettä on aivan järkyttävän huono idea
Ok, hyvä tietää. Tosin käyttäjiä ei tule kuin max 15 kpl.
The Alchemist kirjoitti:
Jos luulit case-sensitiven käyttäjänimen parantavan tietoturvaa, niin suosittelen perehtymään siihen, mitä tietoturva oikeasti on.
Sillä ei ole mitään väliä mitä minä luulen, jos asiakas sanoo mulle palaverissa että KeiJo PiisPanen on eri asia kuin keijo piispanen kirjautuessa. Niin silloin molemmat eivät voi mennä heittämällä läpi.¨
Ja selitäppä nyt miksi ei case-sensitive käyttäjänimi olisi turvallisempi?
Edit:
...
$query = sprintf("SELECT * FROM users WHERE BINARY nimi = '%s' AND salasana = '%s'",
mysql_real_escape_string($_POST["user"]),
$this->valmisteleSalasana($_POST["pass"]));
...?
Ymmärsinköhän nyt oikein, että haluat case-sensitive MySQL-kyselyn?
Jos kyllä, niin kokeile
SELECT * FROM `table` WHERE BINARY `column` = 'value'
Avainsana: BINARY
edit: Kappas, olitkin jo tossa aikasemmassa postauksessa sitä käyttänyt. Koodailun iloa. :-)
kinnala kirjoitti:
edit: Kappas, olitkin jo tossa aikasemmassa postauksessa sitä käyttänyt. Koodailun iloa. :-)
Kiitos kuitenkin vilpittömästä vastauksesta.
qeijo kirjoitti:
Selitäpä nyt miksi ei case-sensitive käyttäjänimi olisi turvallisempi?
En minä tarkoittanut tuota vaan sitä, ettei tietoturva ole mikro-optimointia ja asioiden tarpeetonta monimutkaistamista. Sitä paitsi case-sensitive nimimerkki on täysin merkityksetön asia, kun käyttäjällä on vahva salasana ja tunnukset on säilötty tietokantaan oikeaoppisesti. Nimimerkeillä puljaaminen on sen jälkeen juurikin mikro-optimointia, turhanpäiväistä.
Tietoturvallisuutta kenties olisi se, että vaihdat suoraan PDO:hon sen sijaan, että yrität itse implementoida samat asiat...
Tein tietoturva - "mikro-optimoinnin" siinä ajassa kuin kirjoitit siittä foorumiin nootin. Kumpikohan oli "turhanpäiväisempää".
Millä lailla PDO huomioi case - sensitiven kyselyissä verrattuna minun esimerkkiin?
Turha vetää hernettä nenään, kun se näköjään vain lisää väärinymmärryksiä. Eihän tuo ideakaan edes ollut omasi. En minä tässä kenellekään kuittaillut. Kuvittelin tosin, että asiakkaidenkin kanssa voi neuvotella, eikä vain ottaa parrua takaluukkuun, kun niin käsketään.
The Alchemist kirjoitti:
Turha vetää hernettä nenään, kun se näköjään vain lisää väärinymmärryksiä. Eihän tuo ideakaan edes ollut omasi. En minä tässä kenellekään kuittaillut. Kuvittelin tosin, että asiakkaidenkin kanssa voi neuvotella, eikä vain ottaa parrua takaluukkuun, kun niin käsketään.
Totta.
qeijo kirjoitti:
Millä lailla PDO huomioi case - sensitiven kyselyissä verrattuna minun esimerkkiin?
PDO ei huomioi sitä sen enempää, kuin mysql_query:kään, mutta silti se ei ole syy olla käyttämättä kyseistä rajapintaa. Käyttäessäsi PDO:ta sinun ei itse tarvitse huolehtia syötteen escapetusta vaan syöttäessäsi ne execute:n parametreiksi PDO hoitaa sen puolestasi. Tietokantayhteys on yhtä helposti luotu kuin mysql:llä.
// Putkasta apinoitu
$host = 'localhost';
$dbname = 'tietokannannimi';
$username = 'kayttaja';
$password = 'salasana';
try {
$db = new PDO('mysql:host=' . $host . ';dbname=' . $dbname, $username, $password);
} catch (PDOException $e) {
die("VIRHE: " . $e->getMessage());
}
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->exec('SET CHARACTER SET utf8');Ja itse kysely
$sql = "SELECT * FROM users WHERE username = ? AND password = ?"; $query = $db->prepare($sql); $query->execute(array($_POST['username'], $_POST['password'])); // etc...
Myöskin jos tietoturvan täytyy olla tuota tasoa ei kannata käyttää jokaisella käyttäjällä samaa suolaa vaan luoda jokaiselle käyttäjälle oma, mielellään joka kirjautumiskerralla vaihtuva suola.
Othnos kirjoitti:
mielellään joka kirjautumiskerralla vaihtuva suola.
huh?
Othnos kirjoitti:
Myöskin jos tietoturvan täytyy olla tuota tasoa ei kannata käyttää ...
Ja myöskään tällöin MD5-häshien käyttäminen ei ole kovinkaan hyvä idea. Aihetta lievästi liipaten satuin lukemaan juuri hetki sitten mielenkiintoisen artikkelin.
Grez kirjoitti:
Othnos kirjoitti:
mielellään joka kirjautumiskerralla vaihtuva suola.
huh?
Suojaa "törmäyksiltä", jossa hakkeri on sattunut löytämään saman hashin tuottavan salasanan. Onhan tuo tietenkin joka kirjautumiskerralle yksi kysely lisää ja isossa palvelussa merkittävä tehosyöppö, joten sovitaan, että siitä on enemmän haittaa kuin hyötyä.
Othnos kirjoitti:
Grez kirjoitti:
Othnos kirjoitti:
mielellään joka kirjautumiskerralla vaihtuva suola.
huh?
Suojaa "törmäyksiltä", jossa hakkeri on sattunut löytämään saman hashin tuottavan salasanan. Onhan tuo tietenkin joka kirjautumiskerralle yksi kysely lisää ja isossa palvelussa merkittävä tehosyöppö, joten sovitaan, että siitä on enemmän haittaa kuin hyötyä.
oot ymmärtänyt nyt jotain vähän väärin
Othnos kirjoitti:
Suojaa "törmäyksiltä", jossa hakkeri on sattunut löytämään saman hashin tuottavan salasanan. Onhan tuo tietenkin joka kirjautumiskerralle yksi kysely lisää ja isossa palvelussa merkittävä tehosyöppö, joten sovitaan, että siitä on enemmän haittaa kuin hyötyä.
Itse näkisin että käyttäjäkohtainen suola on hyvä (bcrypt vielä parempi) ja siitäkään en näe haittaa jos suolan vaihtaa vaikka aina kun käyttäjä vaihtaa salasanaansa. Mutta suolan vaihtamisesta jokaisella kirjautumiskerralla ilman salasanan vaihtamista en näe mitään hyötyä. Ainoa teoreettinen hyöty olisi, että jos hyökkääjä dumppailee tietokantaa vähän väliä, niin ei voi seurailla helposti kuinka usein käyttäjät vaihtaa salasanaansa.
Jos käyttäjän on tarkoitus pysyä kirjautuneena pitkään (kuten tällä sivustolla), kirjautuminen toteutetaan usein tallentamalla keksiin hashauksen tulos. Silloin suolan vaihtamisesta joka kirjautumiskerralla on sellainen hyöty, että uusi kirjautuminen tekee vanhat keksit kelvottomiksi, jolloin pelkästään keksejä varastavan hyökkääjän ilo jää lyhyeksi. Toisaalta samalla estetään (tavalliselta käyttäjältä) kirjautuminen monelta eri koneelta samaan aikaan.
Mielestäni tuon saisi paremmin toteutettua arpomalla vaan sopivan pituisen tokenin ja antamalla sen käyttäjälle ja tallettamalla kantaan. En näe mitään järjellistä syytä tai mitään hyötyä tunkea sitä salasanan pohjalta muodostettua tiivistettä käyttäjän selaimelle.
Tietty jos tehdään jotain viritystä, jossa on pakko elää tietokannassa ennestään olevilla kentillä, niin käyhän se noinkin.
samip kirjoitti:
oot ymmärtänyt nyt jotain vähän väärin
Kyseiset kommentit ovat yhtä tyhjänkanssa ja suorastaan huutavat perusteluita.
Toisaalta perehdyttyäni vielä tarkemmin asiaan nuo collisionit ovat tosiaan melko kaukaa haettuja. Mutta auttakaa nyt minua ymmärtämään miten suolan uusiminen ei paranna kyseisessä tekaistussa tapauksessa tietoturvaa.
Kuvitellaan, että md5($suola . $salasana1) ja md5($suola . $salasana2) tuottavat saman hashin, mutta uudella suolalla ne hyvin suurella todennäköisyydellä eroavat jo toisistaan jolloin kyseisen "törmäyksen" salasana ei enää kelpaa.
Othnos kirjoitti:
Kuvitellaan, että md5($suola . $salasana1) ja md5($suola . $salasana2) tuottavat saman hashin, mutta uudella suolalla ne hyvin suurella todennäköisyydellä eroavat jo toisistaan jolloin kyseisen "törmäyksen" salasana ei enää kelpaa.
Siis salasanahan ei yleensä muutu kirjautumisten välillä, joten tuossa nyt sitten on normaalitilanteessa:
md5($suola1 . $salasana) ja md5($suola2 . $salasana)
Eli vaikka nyt toki tiivisteet eroavat toisistaan, niin aikaisemmin mahdollisesti löydetyn törmäyksen salasana kelpaisi edelleen. Nyt vaan hakkerilla on mahdollisesti kaksi erillistä tiivistettä josta jos jompi kumpi sattuisi löytymään, niin salasana olisi selvitetty. Eli nähdäkseni tuo korkeintaan _lisää_ hakkerin mahdollisuutta murtaa salasana.
Eli minun puolesta suolan voi vaihtaa joka kerta kun salasanaakin vaihdetaan, mutta olen edelleen sitä mieltä, että joka kirjautumiskerralla sitä ei kannattaisi vaihtaa.
Grezin logiikka ei päde.
Vaikka löytyisi merkkijono $salasana2, jolle hash($suola . $salasana2) olisi sama kuin hash($suola . $salasana), niin ei voi todellakaan sanoa, että suolan vaihtamisen jälkeen pätisi edelleen hash($suola2, $salasana2) == hash($suola2, $salasana).
Tiivistefunktioiden kulmakivenä on olettama, että jos funktiolle syöttää kaksi eri merkkijonoa, niin niiden tiivisteet ovat erilaiset. Yhteentörmäykset ovat vain harvinaisia poikkeustapauksia. Täten voi oikeastaan sanoa faktana, että jos kaksi eri merkkijonoa '$suola . $salasana' ja '$suola . $salasana2' tuottavat saman tiivisteen, niin on täysin mahdotonta, että niille yhteisen osamerkkijonon ($suola) vaihtamalla tiivisteet edelleen täsmäisivät.
Vaikka hakkeri olisi vanhan suolan ollessa käytössä onnistunut keksimään uuden salasanan (joka on eri kuin alkuperäinen), jolla hän aikaiseksi saman tiivisteen, niin uuteen suolaan vaihtamisen jälkeen järjestelmään murtautuminen olisi edelleen yhtä vaikeaa. Oman salasanansa keksimisestä hän ei hyödy mitään. Edelleen ainoa vaihtoehto uuteen murtautumiseen olisi bruteforcettaa uusi salasana, joka tuottaa uuden suolan kanssa tietokannassa olevan tiivisteen.
Vanhan suolan aikaan pätenyt $salasana2 ei auta prosessissa yhtään, koska olettaman mukaan se on eri kuin $salasana, eikä sen avulla voi päätellä mitään alkuperäisestä salasanasta.
The Alchemist kirjoitti:
Grezin logiikka ei päde.
Joudun sanomaan, että the Alchemistin lukutaito ei päde, koska en kirjoittanut mitään sen suuntaistakaan mihin vastasit.
Grez kirjoitti:
Eli vaikka nyt toki tiivisteet eroavat toisistaan, niin aikaisemmin mahdollisesti löydetyn törmäyksen salasana kelpaisi edelleen.
Miten niin kelpaisi? Tai saattaa kelvata, mutta todella pienellä todennäköisyydellä.
Kuvitellaan, että salasanan ja suolan yhdistys "abc" antaa saman hashin, kuin "bbc", mutta jos vaihdetaan suola, tässä tapauksessa "bc" niin todennäköisyys, että "adc" ja "bdc" tuottavat edelleen samat hashit on olematon.
Mutta kuten jo sanoin nuo törmäykset ovat jo MD5:llä niin pitkissä merkkijonoissa, että todennäköisyys löytää oikea salasana on hyvin suuri verrattuna saman tiivisteen tuottamaan toiseen merkkijonoon (kuka käyttää satoja merkkejä pitkiä salasanoja?), joten tuo mainitsemani suolan vaihtaminen joka kirjautumiskerralla on vain ylimääräistä rasitusta palvelimelle.
Othnos kirjoitti:
Miten niin kelpaisi? Tai saattaa kelvata, mutta todella pienellä todennäköisyydellä.
No myönnetään, että jos salasana on lähes 128 bittiä entropiaa sisältävä, niin silloin se brute forcauksella törmäyksessä löydetty salasana saattaisi olla eri kuin käyttäjän kirjoittama salasana ja se ei tietenkänä kävisi.
Kuitenkin melko tyypillinen 12 merkkinen salasana sisältää entropiaa korkeintaan 94 bittiä (käytössä merkit 32-255), jolloin bruteforcella löydetty törmäys olisi sama salasana 99,999999992 % todennäköisyydellä olettaen että brute forcaaja aloittaa loogisesti lyhyemmistä salasanoista ja etenee pidempiin. Mielestäni tuo ei ole "todella pienellä todennäköisyydellä" vaan "lähes varmasti".
Siis eihän se suolan muuttaminen millään tavalla salasanaa suojaa. Vanha tiiviste ei enää kelpaa suoraan kirjautumiseen, eli toisin sanoen käyttäjän aiempi istunto päättyy. Tietenkin samaan tulokseen pääsee vähemmällä sähläyksellä niin, että kirjautuminen on erikseen ja istunnon tunnisteella ei ole mitään tekemistä salasanan kanssa. Se onkin viisaampaa, jottei siitä varastetusta tunnisteesta saa purettua minkäänlaista salasanaa.
Aihe on jo aika vanha, joten et voi enää vastata siihen.