Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Salasanan tiivisteen päivitys md5:stä

manninen [28.02.2016 21:10:53]

#

Hei!

Rakanetamani sovellus käyttää tällä hetkellä md5 - salausalgoritmia joka on luonnollisesti jo vanhanaikainen. Haluaisin muuttaa sovellukseni käyttämään tuoreempia algoritmeja. Miten tämän toteutus kannattaisi tehdä?

Tarkistanko ensin esim. vanhalla algoritmilla löytyykö vastinetta. Jos löytyy luodaan käyttäjän syötteillä uusi tunniste johon tulevaisuudessa verrataan. Käyttäjän tietoihin syötetään samalla tieto, ettei enää tehdä vanhan algoritmin tarkistusta. Vai miten tämä olisi järkevin toteuttaa ja mikä on tällä hetkellä järkevin algoritmi jota käyttää?

Metabolix [28.02.2016 21:33:39]

#

Puhut varmaan salasanan tiivisteestä, joka on aivan eri asia kuin mikään salaus. Salasanan käsittelyyn on PHP:ssä nykyään hyvät funktiot password_hash ja password_verify, joista on koodivinkki. Tiiviste lasketaan bcrypt-algoritmilla, mutta tarkoitus on, että myöhemmin voidaan saumattomasti vaihtaa muuhun algoritmiin ilman, että koodia tarvitsee muuttaa mitenkään.

Jotta saisit saman tien uuden algoritmin tuoman turvan myös vanhoille käyttäjille, käsittele kaikki vanhat md5-tiivisteet uudella password_hash-funktiolla ja merkkaa niihin, että ne on johdettu vanhoista md5-tiivisteistä. Näin muokatun tiivisteen murtaminen tulee yhtä hitaaksi kuin uudella algoritmilla muutenkin; välissä on vain yksi turha md5-kutsu. Kirjautumisessa tarkasta, onko tiiviste uutta vai vanhaa tyyppiä, ja tarvittaessa laske salasanasta ensin md5-tiiviste. (Jotta tiivisteiden päivitys sujuu turvallisesti etkä vahingossa tuhoa vanhoja tiivisteitä, lisää tauluun uusi sarake uudelle tiivisteelle ja poista vanhat vasta, kun näet, että homma toimii.)

// Uuden tiivisteen laskeminen vanhasta md5-salasanasta; alkuun "md5|" merkiksi.
function tee_uusi_tiiviste($vanha_md5) {
  return "md5|".password_hash($vanha_md5, PASSWORD_DEFAULT);
}
// Salasanan tarkastus (syöte: $salasana; tietokannasta: $tiiviste).
$salasana_ok = false;
$tiiviste_vanhentunut = false;
// Tarkasta, ajetaanko ensin md5.
if (substr($tiiviste, 0, 4) == "md5|") {
  // md5 + password_verify; tiiviste on varmasti vanhentunut.
  $salasana_ok = password_verify(md5($salasana), substr($tiiviste, 4));
  $tiiviste_vanhentunut = true;
} else {
  // password_verify; selvitetään myös, onko tiiviste vanhentunut.
  $salasana_ok = password_verify($salasana, $tiiviste);
  $tiiviste_vanhentunut = password_needs_rehash($tiiviste, PASSWORD_DEFAULT);
}
// Ilmoitetaan, jos salasana on väärä.
if (!$salasana_ok) {
  throw new Exception("Väärä salasana!");
}
// Jos salasana on oikea mutta tiiviste vanhentunut, tehdään uusi tiiviste.
if ($salasana_ok && $tiiviste_vanhentunut) {
  $tiiviste = password_hash($salasana, PASSWORD_DEFAULT);
  // TODO: tallenna uusi $tiiviste
}

manninen [28.02.2016 21:38:46]

#

Kiitän!

Grez [28.02.2016 21:39:50]

#

Jos haluaa oikein hienosti tehdä, niin voi laittaa vielä kentän, joka kertoo että onko käyttäjä vaihtanut salasanaa vai onko se edelleen sama joka kannassa on ollut MD5-tiivistettynä. Tästä olisi hyötyä tilanteessa, missä selviäisi että kanta on vuotanut ennen tiivistealgoritmin vaihtoa. Tosin tietenkin "salasana vaihdettu viimeksi" kenttä ajaa saman asian, jos vaan muutoksen ajankohta on muistisssa.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta