Új jelszótitkosítási eljárás az RC6 óta

Szerző
Üzenet
MyR
Gyakorlott phpBB-s
Gyakorlott phpBB-s


Csatlakozott: 2006.02.03. Péntek 1:00
Hozzászólások: 315
Hozzászólás Elküldve: 2007.10.21. 15:16    Hozzászólás témája: Új jelszótitkosítási eljárás az RC6 óta
Hozzászólás az előzmény idézésével
Tudja valaki, hogy az RC6 óta a jelszavak milyen kódolási műveleten mennek keresztül? Azért kérdezem, mert sok felhasználói azonosítást kérő php alkalmazásom a fórum adatbázisában lévő jelszavakkal hasonlítja össze a felhasználó által megadott jelszót, és eddig mindössze egy md5 függvény használata elegendő volt, hogy össze tudja hasonlítani a jelszavakat, de az RC6-os verzió óta az új jelszókódolási eljárás miatt ezek az alkalmazások most mind meghibásodtak.

Felhasználó profiljának megtekintése Privát üzenet küldése
fberci
Adminisztrátor
Adminisztrátor
Avatar

Csatlakozott: 2005.05.28. Szombat 1:00
Hozzászólások: 7388
Hozzászólás Elküldve: 2007.10.21. 15:20    Hozzászólás témája: phpbb_hash() és phpbb_check_hash()
Hozzászólás az előzmény idézésével
Hogy őszinte legyek, a konkrét kódolási mechanizmust nem ismerem, de az includes/functions.php-ből a phpbb_hash() és a phpbb_check_hash() függvényre lesz szükséged.

Ui.: Már RC5 óta, az RC6 csak apró hibajavítás volt. :)
_________________
Üdv.: fberci
Kereső | Szabályzat | phpBB3 telepítés/frissítés/konvertálás | Útmutatók | Olympus - phpBB3 | Kérlek, ne küldj privát üzenetet nem személyes dologgal kapcsolatban!

Felhasználó profiljának megtekintése Privát üzenet küldése Felhasználó weblapjának megtekintése
MyR
Gyakorlott phpBB-s
Gyakorlott phpBB-s


Csatlakozott: 2006.02.03. Péntek 1:00
Hozzászólások: 315
Hozzászólás Elküldve: 2007.10.21. 15:27    Hozzászólás témája:
Hozzászólás az előzmény idézésével
Köszi, megpróbálok valamit kihámozni ebből a két függvényből, aztán ha sikerült kidolgoznom valami eljárást akkor közzéteszem.

fberci írta:

Már RC5 óta, az RC6 csak apró hibajavítás volt.
RC5-ös verzió alatt nekem még elég volt az md5() függvény használata. :? ---> Hoppá, ez azt jelenti, hogy már az a frissités se volt zökkenőmentes?! :D :D

Felhasználó profiljának megtekintése Privát üzenet küldése
MyR
Gyakorlott phpBB-s
Gyakorlott phpBB-s


Csatlakozott: 2006.02.03. Péntek 1:00
Hozzászólások: 315
Hozzászólás Elküldve: 2007.10.22. 14:24    Hozzászólás témája:
Hozzászólás az előzmény idézésével
Sikerült megcsinálnom. Íme a megoldás, ha valaki integrálni szeretné a fórum beléptető rendszerét a webhely egyes részeivel:

Kód:

include("jelszokodolas.php");
$Kodolo = new PasswordHash(8, true);
$Egyezes = $Kodolo->CheckPassword($_POST["Jelszo"], $Lekerdezes["user_password"]);
if($Egyezes == 1) { // Beengedlek! }

jelszokodolas.php:

Kód:

<?php

class PasswordHash {
   var $itoa64;
   var $iteration_count_log2;
   var $portable_hashes;
   var $random_state;

   function PasswordHash($iteration_count_log2, $portable_hashes)
   {
      $this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

      if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
         $iteration_count_log2 = 8;
      $this->iteration_count_log2 = $iteration_count_log2;

      $this->portable_hashes = $portable_hashes;

      $this->random_state = microtime() . getmypid();
   }

   function get_random_bytes($count)
   {
      $output = '';
      if (($fh = @fopen('/dev/urandom', 'rb'))) {
         $output = fread($fh, $count);
         fclose($fh);
      }

      if (strlen($output) < $count) {
         $output = '';
         for ($i = 0; $i < $count; $i += 16) {
            $this->random_state =
                md5(microtime() . $this->random_state);
            $output .=
                pack('H*', md5($this->random_state));
         }
         $output = substr($output, 0, $count);
      }

      return $output;
   }

   function encode64($input, $count)
   {
      $output = '';
      $i = 0;
      do {
         $value = ord($input[$i++]);
         $output .= $this->itoa64[$value & 0x3f];
         if ($i < $count)
            $value |= ord($input[$i]) << 8;
         $output .= $this->itoa64[($value >> 6) & 0x3f];
         if ($i++ >= $count)
            break;
         if ($i < $count)
            $value |= ord($input[$i]) << 16;
         $output .= $this->itoa64[($value >> 12) & 0x3f];
         if ($i++ >= $count)
            break;
         $output .= $this->itoa64[($value >> 18) & 0x3f];
      } while ($i < $count);

      return $output;
   }

   function gensalt_private($input)
   {
      $output = '$H$';
      $output .= $this->itoa64[min($this->iteration_count_log2 +
         ((PHP_VERSION >= '5') ? 5 : 3), 30)];
      $output .= $this->encode64($input, 6);

      return $output;
   }

   function crypt_private($password, $setting)
   {
      $output = '*0';
      if (substr($setting, 0, 2) == $output)
         $output = '*1';

      if (substr($setting, 0, 3) != '$H$')
         return $output;

      $count_log2 = strpos($this->itoa64, $setting[3]);
      if ($count_log2 < 7 || $count_log2 > 30)
         return $output;

      $count = 1 << $count_log2;

      $salt = substr($setting, 4, 8);
      if (strlen($salt) != 8)
         return $output;

      # We're kind of forced to use MD5 here since it's the only
      # cryptographic primitive available in all versions of PHP
      # currently in use.  To implement our own low-level crypto
      # in PHP would result in much worse performance and
      # consequently in lower iteration counts and hashes that are
      # quicker to crack (by non-PHP code).
      if (PHP_VERSION >= '5') {
         $hash = md5($salt . $password, TRUE);
         do {
            $hash = md5($hash . $password, TRUE);
         } while (--$count);
      } else {
         $hash = pack('H*', md5($salt . $password));
         do {
            $hash = pack('H*', md5($hash . $password));
         } while (--$count);
      }

      $output = substr($setting, 0, 12);
      $output .= $this->encode64($hash, 16);

      return $output;
   }

   function gensalt_extended($input)
   {
      $count_log2 = min($this->iteration_count_log2 + 8, 24);
      # This should be odd to not reveal weak DES keys, and the
      # maximum valid value is (2**24 - 1) which is odd anyway.
      $count = (1 << $count_log2) - 1;

      $output = '_';
      $output .= $this->itoa64[$count & 0x3f];
      $output .= $this->itoa64[($count >> 6) & 0x3f];
      $output .= $this->itoa64[($count >> 12) & 0x3f];
      $output .= $this->itoa64[($count >> 18) & 0x3f];

      $output .= $this->encode64($input, 3);

      return $output;
   }

   function gensalt_blowfish($input)
   {
      # This one needs to use a different order of characters and a
      # different encoding scheme from the one in encode64() above.
      # We care because the last character in our encoded string will
      # only represent 2 bits.  While two known implementations of
      # bcrypt will happily accept and correct a salt string which
      # has the 4 unused bits set to non-zero, we do not want to take
      # chances and we also do not want to waste an additional byte
      # of entropy.
      $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';

      $output = '$2a$';
      $output .= chr(ord('0') + $this->iteration_count_log2 / 10);
      $output .= chr(ord('0') + $this->iteration_count_log2 % 10);
      $output .= '$';

      $i = 0;
      do {
         $c1 = ord($input[$i++]);
         $output .= $itoa64[$c1 >> 2];
         $c1 = ($c1 & 0x03) << 4;
         if ($i >= 16) {
            $output .= $itoa64[$c1];
            break;
         }

         $c2 = ord($input[$i++]);
         $c1 |= $c2 >> 4;
         $output .= $itoa64[$c1];
         $c1 = ($c2 & 0x0f) << 2;

         $c2 = ord($input[$i++]);
         $c1 |= $c2 >> 6;
         $output .= $itoa64[$c1];
         $output .= $itoa64[$c2 & 0x3f];
      } while (1);

      return $output;
   }

   function HashPassword($password)
   {
      $random = '';

      if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
         $random = $this->get_random_bytes(16);
         $hash =
             crypt($password, $this->gensalt_blowfish($random));
         if (strlen($hash) == 60)
            return $hash;
      }

      if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
         if (strlen($random) < 3)
            $random = $this->get_random_bytes(3);
         $hash =
             crypt($password, $this->gensalt_extended($random));
         if (strlen($hash) == 20)
            return $hash;
      }

      if (strlen($random) < 6)
         $random = $this->get_random_bytes(6);
      $hash =
          $this->crypt_private($password,
          $this->gensalt_private($random));
      if (strlen($hash) == 34)
         return $hash;

      # Returning '*' on error is safe here, but would _not_ be safe
      # in a crypt(3)-like function used _both_ for generating new
      # hashes and for validating passwords against existing hashes.
      return '*';
   }

   function CheckPassword($password, $stored_hash)
   {
      $hash = $this->crypt_private($password, $stored_hash);
      if ($hash[0] == '*')
         $hash = crypt($password, $stored_hash);

      return $hash == $stored_hash;
   }
}

?>

Felhasználó profiljának megtekintése Privát üzenet küldése
fberci
Adminisztrátor
Adminisztrátor
Avatar

Csatlakozott: 2005.05.28. Szombat 1:00
Hozzászólások: 7388
Hozzászólás Elküldve: 2007.10.22. 15:12    Hozzászólás témája:
Hozzászólás az előzmény idézésével
Csak egy megjegyzés, hogy szerintem egyszerűbb közvetlenül a phpBB függvényeit használni, a munkamenetkezelésről nem is beszélve.
_________________
Üdv.: fberci
Kereső | Szabályzat | phpBB3 telepítés/frissítés/konvertálás | Útmutatók | Olympus - phpBB3 | Kérlek, ne küldj privát üzenetet nem személyes dologgal kapcsolatban!

Felhasználó profiljának megtekintése Privát üzenet küldése Felhasználó weblapjának megtekintése
MyR
Gyakorlott phpBB-s
Gyakorlott phpBB-s


Csatlakozott: 2006.02.03. Péntek 1:00
Hozzászólások: 315
Hozzászólás Elküldve: 2007.10.22. 15:30    Hozzászólás témája:
Hozzászólás az előzmény idézésével

fberci írta:

Csak egy megjegyzés, hogy szerintem egyszerűbb közvetlenül a phpBB függvényeit használni, a munkamenetkezelésről nem is beszélve.
Ez így van, amit én írtam az csak arra az esetre jó, hogy át tudd konvertálni a felhasználó által megadott jelszót, hogy utána össze tudd hasonlítani az adatbázisban lévővel.

Rosszul írtam, ez tulajdonképpen nem egy komplett integrációja a fórum beléptető rendszerének. A jelszokodolas.php csak egy kódolási eljárást foglal magába. Viszont ha megnézed, akkor láthatod, hogy a fórumba is ebből a fájlból szedegették össze a "hozzávalókat".

Visszatérve az előbbihez, a legszebb az lett volna, ha a functions.php függvényeit használtam volna fel ehhez a felhasználói azonosításhoz, de sajnos nagyon bonyolultak voltak azok a függvények, így inkább a könnyebb megoldást választottam. Sokak szenvednek az RC6 óta az integrációval, így biztos vagyok benne, hogy nemsokára lesz kidolgozva erre valami módszer.

Viszont észrevettem, hogy csak néhány felhasználó esetében működik ez a módszer. Rájöttem, hogy csak azoknál a felhasználóknál működik, akiknél az user_pass_convert adatbázismező értéke 1. Ha jól tudom ez azt jelenti, hogy a jelszavuk már az új kódolási eljárásokkal van-e kódolva. Nem tudom, hogy miért, de a fórum nem a frissítéskor, hanem a felhasználó a frissítés utáni első bejelentkezésekor kódolja át a felhasználó jelszavát az új formába, így azon felhasználók esetében, akik még nem jelentkeztek be a fórumba az RC6-os verzió óta nem fog működni.

Felhasználó profiljának megtekintése Privát üzenet küldése
fberci
Adminisztrátor
Adminisztrátor
Avatar

Csatlakozott: 2005.05.28. Szombat 1:00
Hozzászólások: 7388
Hozzászólás Elküldve: 2007.10.22. 15:45    Hozzászólás témája:
Hozzászólás az előzmény idézésével

MyR írta:

Nem tudom, hogy miért, de a fórum nem a frissítéskor, hanem a felhasználó a frissítés utáni első bejelentkezésekor kódolja át a felhasználó jelszavát az új formába, így azon felhasználók esetében, akik még nem jelentkeztek be a fórumba az RC6-os verzió óta nem fog működni.
Ez logikus, hiszen a különböző kódolások nem konvertálhatók át egymásba, mivel nem visszafejthető kódolásról van szó. Tehát belépéskor a phpBB először is megnézi, hogy az adatbázisban lévő hashelt jelszó régi-e vagy új (a hash hosszúságából ez megállapítható), ennek függvényében azonosítja a felhasználót, majd ha az adatbázisban szerelő hash régi fajta volt, akkor a megadott jelszóból (amit éppen megadott a felhasználó, tehát mindenféle titkosítás nélküli) legenerál egy új fajta hasht.

A külön mező azt hiszem még a konvertálóval kapcsolatos, az nem most került bele a rendszerbe.

Nem értem miért bonyolultak azok a függvények, nem kell, hogy pontosan értsd őket, elég csak használni. Ha ellenőrizni akarod a jelszavakat, akkor ott van a phpbb_check_hash(), ha eltárolni, akkor a phpbb_hash().

De még mindig állítom, hogy legegyszerűbb a teljes munkamenetkezelést átvenni (néhány sor), ekkor a phpBB ezt az egész terhet leveszi a vállunkról.
_________________
Üdv.: fberci
Kereső | Szabályzat | phpBB3 telepítés/frissítés/konvertálás | Útmutatók | Olympus - phpBB3 | Kérlek, ne küldj privát üzenetet nem személyes dologgal kapcsolatban!

Felhasználó profiljának megtekintése Privát üzenet küldése Felhasználó weblapjának megtekintése
MyR
Gyakorlott phpBB-s
Gyakorlott phpBB-s


Csatlakozott: 2006.02.03. Péntek 1:00
Hozzászólások: 315
Hozzászólás Elküldve: 2007.10.22. 17:30    Hozzászólás témája:
Hozzászólás az előzmény idézésével

fberci írta:

Ez logikus, hiszen a különböző kódolások nem konvertálhatók át egymásba, mivel nem visszafejthető kódolásról van szó.
Tényleg, csak így lehetséges. Erre nem is gondoltam. :)

fberci írta:

Nem értem miért bonyolultak azok a függvények, nem kell, hogy pontosan értsd őket, elég csak használni. Ha ellenőrizni akarod a jelszavakat, akkor ott van a phpbb_check_hash(), ha eltárolni, akkor a phpbb_hash().
Először én is így gondoltam, de észrevettem, hogy az egyik függvény meghív egy másikat, az egy harmadikat... A végén ott tartok, hogy már lasssan az egész functions.php fájlt include()-olnom kell, az meg ugye nem olyan egyszerű, hogy csak include("functions.php") aztán jóvan.

Vagy én gondolkozok rosszul? Hogyan gondoltad?

Felhasználó profiljának megtekintése Privát üzenet küldése
fberci
Adminisztrátor
Adminisztrátor
Avatar

Csatlakozott: 2005.05.28. Szombat 1:00
Hozzászólások: 7388
Hozzászólás Elküldve: 2007.10.22. 18:19    Hozzászólás témája:
Hozzászólás az előzmény idézésével
De, így gondoltam. Bár - én mint írtam - nem bánnám, ha be kéne include-olni az egész includes/functions.php-t, sőt az összes többi fájlt se (bár, ahogy nézem, az unique_id()-n kívül nincs is más külső függvény meghívva). :)
_________________
Üdv.: fberci
Kereső | Szabályzat | phpBB3 telepítés/frissítés/konvertálás | Útmutatók | Olympus - phpBB3 | Kérlek, ne küldj privát üzenetet nem személyes dologgal kapcsolatban!

Felhasználó profiljának megtekintése Privát üzenet küldése Felhasználó weblapjának megtekintése
MyR
Gyakorlott phpBB-s
Gyakorlott phpBB-s


Csatlakozott: 2006.02.03. Péntek 1:00
Hozzászólások: 315
Hozzászólás Elküldve: 2007.10.23. 20:07    Hozzászólás témája: Egy kis javítás
Hozzászólás az előzmény idézésével
Egy kis módosítással elérhető, hogy a még régi, md5-ös kódolású jelszavak esetében is működjön:

Ha ezt a sort:

Kód:

if($Egyezes == 1) { // Beengedlek! }

lecseréled erre:

Kód:

if(($Egyezes == 1) || (md5($_POST["Jelszo"]) == $Lekerdezes["user_password"])) { // Beengedlek! }

Felhasználó profiljának megtekintése Privát üzenet küldése
Hozzászólások megtekintése:  

Nem készíthetsz új témákat ebben a fórumban.
Nem válaszolhatsz egy témára ebben a fórumban.
Nem módosíthatod a hozzászólásaidat a fórumban.
Nem törölheted a hozzászólásaidat a fórumban.
Nem szavazhatsz ebben fórumban.

Hirdetés
Hirdetés