Lühidalt: Paroole salvestate PHP-s funktsiooniga password_hash() ja kontrollite funktsiooniga password_verify(). Vaikeväärtus PASSWORD_DEFAULT kasutab praegu bcrypt'i, PHP 8.4-st kuluteguriga 12; kus PHP on Argon2-ga kompileeritud, on PASSWORD_ARGON2ID hea alternatiiv. Vanad MD5- või SHA-1-räsid viite üle, pakkides need kohe password_hash'i sisse ja asendades järgmisel sisselogimisel otsese räsiga.
Mis pistmist on andmebaasi lekkel teie räsidega
Pärast veebiserveri sissemurdmist on andmebaas üks esimesi sihtmärke. Kes saab serveris koodi käivitada, nagu PHP2Shelli puhul võimalik, loeb ka rakenduse ligipääsuandmed ja seega kasutajakontode tabeli. See, kas selle paroolid muutuvad loetavaks tundide või aastate pärast, ei otsustu rünnakupäeval, vaid programmeerimisel.
Üllatavalt paljud rakendused salvestavad paroole veel meetoditega, mida selleks kunagi ei mõeldud: MD5, SHA-1, lihtne SHA-256 või isegi pööratavalt krüpteeritult. Need meetodid on kiired ja just see on probleem. Ründajad saavad nendega sekundis läbi proovida väga palju kandidaate.
PHP-l on juba ammu kaasas lahendus, mis arvutab aeglaselt, loob iga parooli jaoks automaatselt soola (salt) ning salvestab meetodi ja parameetrid räsi enda sisse. Peate seda ainult järjekindlalt kasutama.
password_hash PHP-s: bcrypt või Argon2id?
password_hash() tunneb mitut meetodit. Valik PHP käsiraamatu järgi:
| Konstant | Meetod | Märkus |
|---|---|---|
PASSWORD_DEFAULT |
praegu bcrypt | vaikimisi, võib tulevastes versioonides muutuda |
PASSWORD_BCRYPT |
bcrypt | kulutegur PHP 8.4-st vaikimisi 12, varem 10; loevad ainult esimesed 72 baiti |
PASSWORD_ARGON2I |
Argon2i | PHP 7.2-st, ainult kui PHP on ehitatud Argon2 toega |
PASSWORD_ARGON2ID |
Argon2id | PHP 7.3-st, sama eeldus |
OWASP soovitab Argon2id-i esimese valikuna, vähemalt 19 MiB mälu, kahe läbimise ja ühe lõimega, ning bcrypt'i eelkõige olemasolevate süsteemide jaoks. Enamiku PHP rakenduste puhul on vahe praktikas väiksem kui vahe suvalise nende meetodite ja MD5 vahel. Olulisem on, et kasutate üldse ühte neist ja kohandate parameetreid regulaarselt.
Kas Argon2id on saadaval, näitab lühike test:
<?php
var_dump(defined('PASSWORD_ARGON2ID'));
var_dump(password_algos());
Salvestamine ja kontrollimine: täielik muster
Järgmine näide näitab registreerimist ja sisselogimist aegunud räsi automaatse uuendamisega. Pikkuse kontroll kaitseb bcrypt'i 72 baidi piiri eest:
<?php
declare(strict_types=1);
const PASSWORT_ALGO = PASSWORD_DEFAULT;
function passwortSpeichern(string $passwort): string
{
if (strlen($passwort) > 72) {
throw new InvalidArgumentException('Passwort zu lang für das gewählte Verfahren.');
}
return password_hash($passwort, PASSWORT_ALGO);
}
function passwortPruefen(string $eingabe, string $gespeicherterHash, callable $hashAktualisieren): bool
{
if (!password_verify($eingabe, $gespeicherterHash)) {
return false;
}
if (password_needs_rehash($gespeicherterHash, PASSWORT_ALGO)) {
$hashAktualisieren(password_hash($eingabe, PASSWORT_ALGO));
}
return true;
}
strlen() loeb baite, mitte märke. See on siin tahtlik, sest bcrypt'i piir viitab baitidele. Andmebaasi veerg peaks käsiraamatu kohaselt mahutama rohkem kui 60 märki, 255 on hea valik. Ärge seadke kunagi oma soola: see valik on vananenud ja seda eiratakse PHP 8.0-st alates.
PHP 8.4-le üleminekuga tõuseb bcrypt'i vaikimisi kulutegur 10-lt 12-le. Olemasolevad räsid tõstetakse tänu password_needs_rehash() järgmisel sisselogimisel automaatselt üles. Tugevalt koormatud süsteemides tasub enne ülemineku tegemist teha sisselogimise lühike koormustest.
Mõõtke kulutegurit oma tootmisserveris. Üksik kontroll peaks tunduvalt arvutusaega võtma, kuid jääma selgelt alla sekundi, et sisselogimised koormuse korral kitsaskohaks ei muutuks.
Vanade MD5- ja SHA-1-räside asendamine
Tegelik väljakutse on tavaliselt olemasolev andmestik. Paroole endid te ei tea, seega ei saa neid lihtsalt uuesti räsida. Ootamine, kuni iga kasutaja uuesti sisse logib, jätab passiivsed kontod kaitseta. OWASP kirjeldab seetõttu kahesammulist lähenemist:
- Pakkige kohe sisse: Mähkige iga olemasolev MD5- või SHA-1-väärtus skriptiga
password_hash()sisse ja salvestage märgistusega, näiteks veerushash_typ. - Kontrollige sisselogimisel: Märgistatud kontode puhul arvutage sisend esmalt vana meetodiga ümber ja kontrollige siis
password_verify()abil sissepakitud väärtuse vastu. - Asendage otse: Pärast edukat sisselogimist looge selgest tekstist tavaline räsi ja eemaldage märgistus.
- Puhastage jääk: Kontod, millel on pärast kindlaksmääratud tähtaega veel sissepakitud räsid, seadke parooli lähtestamisele.
<?php
// 1. aste (ühekordselt skriptiga): $neu = password_hash($alterMd5Wert, PASSWORD_DEFAULT);
// 2. ja 3. aste sisselogimisel:
if ($konto['hash_typ'] === 'md5-umhuellt') {
$ok = password_verify(md5($eingabe), $konto['passwort_hash']);
if ($ok) {
$speichere(password_hash($eingabe, PASSWORD_DEFAULT), 'direkt');
}
}
Sissepakitud räsid on paremad kui paljad MD5-väärtused, kuid nõrgemad kui otsesed räsid. Need on üleminekulahendus, mitte eesmärk. Pärast intsidenti, mille puhul andmebaas võib olla mõjutatud, ei asenda see ümberseadmine kasutajate üleskutset oma paroole muuta. Millised jäljed sellisele intsidendile viitavad, kirjeldab Kas ma olen juba kompromiteeritud?.
Pepper, krüpteerimine ja muud eksiteed
Mõned ideed kõlavad turvalisemana, kuid annavad vähe või teevad kahju:
- Oma räsikonstruktsioonid, näiteks mitmekordne SHA-256 ise loodud soolaga, on kiiremad kui bcrypt ja seetõttu nõrgemad.
- Krüpteeritud paroolid on pööratavad. Kui võti asub samas serveris, ei kaitse krüpteerimine pärast sissemurdmist peaaegu üldse.
- Pepper, see tähendab kõigi paroolide jaoks salajane lisaväärtus, võib olla täiendav kiht, kui seda hoitakse andmebaasist eraldi. See ei asenda aga head räsimeetodit ja raskendab hilisemaid vahetusi.
- Eelräsimine enne bcrypt'i, et 72 baidi piirist mööda minna, kätkeb OWASP-i andmetel omi riske. Selge pikkusepiir või Argon2id on lihtsam.
Ka uute paroolide reeglite puhul tasub vaadata tehnika taset: pikkus kaitseb rohkem kui keerukad erimärkide nõuded ning väga levinud või juba andmelekketes esinenud paroolid tuleks tagasi lükata. Kindlate intervallidega sunnitud vahetused ilma põhjuseta viivad kogemuse põhjal pigem etteaimatavate mustriteni kui tugevamate paroolideni.
Sisselogimissüsteemides ei kuulu paroolid kunagi üksi: administraatorite kaheastmeline meetod ja pidur massilistele sisselogimiskatsetele täiendavad salvestamist. Mõlemat käsitleb juhend Admin-sisselogimiste kaitsmine jõhkra jõu (brute force) rünnakute vastu. Lähtestuslinkide ja ühekordsete koodide jaoks kehtivad muud reeglid, vt Turvalised juhuarvud ja tokenid PHP-s. Ülevaate muudest funktsioonidest annab PHP sisseehitatud turvafunktsioonid.
Kuidas PHP SOS konkreetselt aitab?
- Me kontrollime, kuidas teie rakendus ja pistikprogrammid paroole salvestavad, ning leiame vananenud meetodid ka kõrvalfunktsioonidest.
- Me planeerime andmestiku ümberseadmise sissepakkimise, sisselogimisel migreerimise ja jääkide tähtajaga.
- Me sobitame kuluteguri või Argon2 parameetrid teie serveritele.
- Pärast intsidenti toetame otsustamisel paroolide lähtestamise üle ja selle tehnilisel elluviimisel.
Oma PHP-tarkvara kontrolli pakume turvaauditi ja läbitungimistestina.
Korduma kippuvad küsimused
Millist algoritmi kasutab password_hash koos PASSWORD_DEFAULT-iga?
Praegu bcrypt'i. PHP käsiraamat juhib tähelepanu, et vaikimisi väärtus võib muutuda, kui lisandub tugevamaid meetodeid. Seetõttu peaks andmebaasi veerg mahutama rohkem kui 60 märki; käsiraamat nimetab heaks valikuks 255.
Kas peaksin paroole krüpteerima, mitte räsima?
Ei. Krüpteeritud paroole saab võtmega uuesti lugeda ja see võti asub tavaliselt samas serveris. Parooliräsi on ühesuunaline tänav: rakendus saab ainult kontrollida, kas sisend sobib.
Kui kõrge peaks olema bcrypt'i kuluteguri?
PHP 8.4-st on vaikeväärtus 12, varem oli 10. OWASP nimetab alumiseks piiriks 10 ja soovitab minna nii kõrgele, kui teie serverid välja kannatavad. Mõõtke oma riistvaral, kui kaua kontroll aega võtab.
Mida tähendab bcrypt'i 72 baidi piir?
bcrypt arvestab ainult parooli esimest 72 baiti, kõik sellele järgnev kärbitakse. Täpitähtede puhul loeb üks märk sageli kahe baidina. Piirake pikkust seetõttu selgesõnaliselt või kasutage Argon2id-i, kui teie PHP on sellega kompileeritud.
Kas kasutajad peavad pärast sissemurdmist oma paroole muutma?
Kui ei saa välistada, et andmebaas on lekkinud, peaksite selle algatama. Head räsid aeglustavad murdmist oluliselt, kuid nõrgad paroolid jäävad ründajale haavatavaks. Kas lisaks on teatamiskohustus, selgitage oma andmekaitsespetsialistiga.