Autor Zpráva
bukaJ
Profil
Na funkci crypt() se mi líbí, že v hashi uchovává sůl i typ použitého algoritmu.
Ve stávajících projektech mám desetitisíce uživatelů, kteří mají hashe dělané funkcí md5(pass) a rád bych hashování změnil na crypt().

Existuje způsob, jak převést stávající MD5 hash do tvaru hashe pro funkci crypt bez znalostí původního hesla?

A teď to důležité: je jasné, že hashování je jednocestný proces, takže přímá cesta neexistuje. Nicméně velké množství saltovacích algoritmů pro md5 používá už samotný hash hesla, tedy např.:
<?php
  $hash = md5($salt . md5($pass) );
  //                  ^^^^^^^^^^ - samotný hash - místo něho lze dosadit existující hash hesla
?>

Napadá mě, jestli něco takového nepoužívá i funkce crypt() s algoritmem md5 (argument $1$). Zkoušel jsem hledat na netu, zkoumal jsem i zdrojové kódy PHP, ale nejsem céčkař, to mi nic nepřineslo (nevyznal jsem se v tom).

Zkoušel jsem porovnat různé základní podoby způsobem:
<?php
  $crypthash_real = crypt('heslo', '$1$saltsalt');
  $crypthash_fake = '$1$saltsalt$'.base64_encode(md5( md5('heslo') . 'saltsalt', TRUE));
?>
ale na první pohled je jasné, že base64 není tím správným kódováním hashe.

Předem díky za odpovědi.

Dodatek:
Vím, že toto není nutné, že mohu u existujících uživatelů detekovat typ hashe a podle toho použít odpovídající ověření přihlášení uživatele, ale takové řešení se mi nelíbí a proto hledám nějaké přímočaré jednorázové řešení.
meris
Profil
Ahoj,
nejsem si jistý co přesně by jsi chtěl udělat. Jestli jde jen o to nepoužívat pouze md5(heslo),protože existují databáze dat a k nim příslušným md5 otiskům, tak mě napadá jednoduché připadní funkce crypt nad aktuálnimi daty a volat ji takto:
$hash_pass = crypt ( md5($heslo), "$1$salt");

a všechny hesla uživatelů pak můžes pomocí skriptu překódovat.

druhý způsob jak se md5 zbavit je postupně, k uživateli si přidáš sloupec "typ_hashe" a podle toho jej ověřit a do db pak uložit crypt. Zatři měsice budeš mít převedeny všechny aktivní uživatele, tak těm zbývajícím změníš heslo a pošleš na mail. A typ_hashe smažeš.
bukaJ
Profil
Tak jsem našel a prošel zdroj funkce crypt_md5 s výsledkem, že převod existujích hashí není možný, protože se tam heslo spojuje se solí v nehashovaném tvaru.

meris:
„...tak mě napadá jednoduché připadní funkce crypt nad aktuálnimi daty...“

Díky, to je dobrý nápad, to mě nenapadlo. Ale tím se snižuje univerzálnost - některé systémy nativně umí crypt() používat.

Ten sloupec typ_hashe není třeba, tvar hashe jasně prozradí typ použitého algoritmu.

Výsledek je tedy nutné podmíněné testování podle tvaru uložené hashe (níže v příkladu) a jeho následná aktualizace při přihlášení uživatele.

<?php
  // Ověření uživatele
  function checkPass($pass, $hash) {
    return getHash($pass, $hash) === $hash;
  }
  
  // Získání hashe
  // pokud není salt, vytvoří se nový pro algoritmus blowfish
  function getHash($pass, $hash = NULL) {
    $_crypt_a64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    
    if(is_null($hash))
      $hash = '$2a$10$'.substr(str_shuffle($_crypt_a64),0,22);
    elseif(strlen($hash) == 32 && preg_match('/^[a-z0-9]+$/', $hash))
      return md5($pass);
    else
      return crypt($pass, $hash);
  }
?>

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