« 1 2 »
Autor Zpráva
Kubo2
Profil
Mám nějaký text, zakódovaný napr. hashovacím spôsobom sha1.

Taký zakódovaný ho mám uložený v databázi. Chcem urobiť (o deň neskôr) z databáze výstup tohto textu. Ako ho mám opäť rozkódovať ?
noName
Profil *
"rozkódování" není možné :) Jinak by to bylo přeci k ničemu.
Kubo2
Profil
fúha... To je blbé :-]


A neexistuje nejaká hashovacia "abeceda" ?

Veď ten hash v tom kódovaní predsa musí mať nějaký systém ...
Magnus123
Profil
Tak samozřejmě, že je v tom nějaký systém. Ale kdyby to šlo rozkódovat, tak k čemu by ten hash byl? Bylo by to pak stejné, jako bys to vůbec nehashoval. K čemu vůbec potřebuješ ten text zakódovat a potom vypsat v čisté podobě?
Mároš
Profil
Nevím jak sha1, ale u MD5 se mi podařilo "vrátit" moje vlastní zahashované heslo. Mělo 6 znaků, jen malá eng abeceda, a trvalo to asi 7 hodin na čtyřjádru s 8GB ram :) Bylo to pomocí bruteforce metody :D Takže to asi jde, ale nějak to nemá cenu / smysl. Protože MD5 i SHA1 je jen otisk daného stringu nebo čehokoli.
Zechy
Profil
Mároš:
Obojí se dá samozřejmě rozkodovat, jenže záleží také na délce a složitosti zadaného stringu. Jak jsem jednou čet na netu - rozkodování hesla o 8 znacích se všemi speciálními znaky by trvalo pár milionů let. (Pokud si to pamatuju přesně ještě :-)
Joker
Profil
Kubo2:
Viz Nejčastější potíže s PHP (FAQ).
Mimochodem, doporučuji prostudovat i ty ostatní body.

Mároš:
Ano, pokud o tom hesle jsou k dispozici ještě další informace kromě hashe a je jich tolik, že ze všech kolizních řetězců je splňuje jen jeden, dá se pak to heslo rekonstruovat (pro 6-znakové heslo nejspíš to, že je to 6 znaků a všechny jsou malá písmena anglické abecedy bude stačit).
Ale ze samotného hashe to nejde.
Joker
Profil
Zechy:
Obojí se dá samozřejmě rozkodovat
Ani jedno se samozřejmě rozkódovat nedá. Hash neobsahuje konkrétní informaci o datech, kterých je otiskem.
Samozřejmě je možné k hodnotě hashe najít třeba milión kolizních řetězců (jejichž hash je ta daná hodnota). Ale bez dalších informací není možné určit, který z nich byl ten původní vstup.
TomasJ
Profil
Kubo2:
Tady ti předám svoji třídu na šifrování. Pokud neznáš zdrojový kód, je prakticky nemožné výsledek rozluštit. Nechal jsem se z části inspirovat funkcí str_rot13 kterou jsem upravil podle svého.

class SifrovaciFunkce{
  private $ed,
          $chr;
  
  public function __construct(){
    $this->ed  = false;
    $this->chr = 'QWERTZUIOPASDFGHJKLYXCVBNM01234qwertzuiopasdfghjklyxcvbnm=+56789/\\'; //Pokud budeš měnit znaky, dej si pozor, aby počet znaků po vydělení číslem 2, dal vždy celé číslo (tzn. aby počet znaků byl sudý)
  }
 
  private function shift($str){
    $ln = strlen($str);
    $rtn = "";
    if(!$this->ed){
      for($i=0;$i<$ln;$i++) $rtn.= chr(ord($str[$i])+$i*$i+2);
    }
    else{
      for($i=0;$i<$ln;$i++) $rtn.= chr(ord($str[$i])-$i*$i-2);
    }
    return $rtn;
  }
  
  private function rot($str){
    $out = "";
    $chrsln = strlen($this->chr);
    for($i=0;$i<strlen($str);$i++){
      $chr = substr($str,$i,1);
      if(stripos($this->chr,$chr)>-1){
        for($a=0;$a<$chrsln;$a++){
          $chr2 = substr($this->chr,$a,1);
          if($chr==$chr2){
            $p = $chrsln/2;
            $chr2 = substr($this->chr,$p-($p*2-$a),1);
            if($a+$p+1>$p*2) $out.= substr($this->chr,$p-($p*2-$a),1);
            else $out.= substr($this->chr,$a+$p,1);
          }
        }
      }
      else $out.=$str[$i];
    }
    return $out;
  }
  
  public function encode($str){
    $this->ed = false;
    return $this->shift($this->rot(base64_encode($str)));
  }
  
  public function decode($str){
    $this->ed = true;
    return base64_decode($this->rot($this->shift($str)));
  }
  
  public function __destruct(){
    unset($this->ed);
    unset($this->chr);
  }
}

Použití je pak jednoduché:
$Sifrovani = new SifrovaciFunkce;
$nezakodovane = "ahoj";
$zakodovane = $Sifrovani->encode($nezakodovane);
$rozkodovane = $Sifrovani->decode($zakodovane);
echo "Original: $nezakodovane<br>Zakodovane: $zakodovane<br>Rozkodovane: $rozkodovane";

Upozorňuji, že daná šifrovací funkce nemusí pracovat správně s kódováním UTF-8. Pokud budeš chtít předělat na UTF-8 tuto funkci, použij funkce
mb_strlen();
mb_substr();
mb_strpos();
za funkce které tam jsou.

Ukázka:
Original: Věta která je zakódovaná.
Zakodovane: pWR@u�“Š�˝ÔĆË3k‰łśő->e«ÝÚu˝¸ z‡Ô
Rozkodovane: Věta která je zakódovaná.

EDIT: Přejmenoval jsem funkci z Hash na šifrovací, na základě mého mylného tvrzení, které mi vyvrací Alphard v [#10]
Alphard
Profil
Uvedenou šifrovací třídu rozhodně nelze označit jako hash. U hashe očekávám tyto vlastnosti.

TomasJ:
Pokud neznáš zdrojový kód, je prakticky nemožné výsledek rozluštit.
Toto je velmi odvážné tvrzení a myslím, že byste byl překvapený, co je možné. Němci si to před šedesáti lety taky mysleli...
TomasJ
Profil
Alphard:
Pardon, není to Hash funkce, ale funkce na zašifrování. Nicméně je to postačující, a ovšem, že na žádné aplikace, které vyžadují vysokou bezpečnost, se nedá použít tato třída, ale SHA, MD5 a podobné (což už rozluštit lze jen zdlouhavou metodou bruteforce).
1Pupik1989
Profil
Mezi námi, věta co je zahashovaná, nepatří do rukou nikomu jinému, tudíž jí nemá cenu dávat k dispozici veřejně.
Rfilip
Profil
brureforcem se da prolomit cokoliv,jde jen to za jak dlouho
TomasJ
Profil
1Pupik1989:
To je pravda, toto se dá použít spíš na účely, při kterých je potřeba nějaký řetězec někam uložit a mít možnost jej následně rozluštit. Zvýrazněno: Já tuto funkci používám na info o uživateli, které se nemění a ukládám ho do cookie. V případě načtení těchto dat mi odpadá nutnost připojení k MySQL databázi. Cookie je zakódované z důvodu, že jsou v něm data, která při změně mohou dát vyšší pravomoce uživateli. To jen tak okrajově, k čemu že se moje zmíněná třída dá použít.

Rfilip:
Což jsem psal v [#11] ...
Mimochodem takový řetězec "pWR@u�“Š�˝ÔĆË3k‰łśő->e«ÝÚu˝¸ z‡Ô" bys odteď ani na smrtelné posteli neměl rozluštěný ;)
Protože: Neznáš délku originálního řetězce. Neznáš znaky obsažené v originálním řetězci. Nevíš, jak právě zkoušený řetězec má po zakódování vypadat (za předpokladu, že neznáš metodu kódování). Můžeš zkoušet bruteforce, ale s největší pravděpodobností se výsledku nedožiješ. :)
Rfilip
Profil
aha, to jsem musel nejak prehlidnout :(
1Pupik1989
Profil
Já používám akorát sha512 na hesla, přičemž originální string znát nepotřebuji. Nikde jinde jsem hash nepotřeboval.

TomasJ: Neznám řetězec, který by byl potřeba uložit a následně rozkódovat nebo rozhashovat.
TomasJ
Profil
1Pupik1989:
Přečti si pořádně co jsem psal v [#14]. Píšu tam, kdy se toto dá použít.
Majkl578
Profil
TomasJ:
Já tuto funkci používám na info o uživateli, které se nemění a ukládám ho do cookie. V případě načtení těchto dat mi odpadá nutnost připojení k MySQL databázi. Cookie je zakódované z důvodu, že jsou v něm data, která při změně mohou dát vyšší pravomoce uživateli.
To je pěkné, nicméně tím, že jsi tu uvedl implementaci tvého šifrování, přestává platit tvůj předpoklad „nevíš, že …
Cokoliv jde zakódovat a znovu rozkódovat v žádném případě nejde považovat za hash (viz [#10] od Alpharda). A pokud už opravdu chci šifrování a ne hash, použiji nějaké kvalitní existující, pravděpodobně symetrické řešení, např. AES (Rijndael).
1Pupik1989
Profil
TomasJ: O uživateli existuje něco tak důvěrného (kromě hesla), že se to musí kódovat? To je jen dotaz. Já uložím přezdívku, práva a e-mail do session, to je asi celé, takže tuto techniku moc nechápu.
TomasJ
Profil
1Pupik1989:
Já uložím přezdívku, práva a e-mail do session,
Já do session ukládat nemohu, neboť session nepracuje správně s jedním mým skriptem. Tak to řeším pomocí cookie a tohoto šifrování. Nezašifrované by se to dalo změnit, a tím že by se to změnilo, by dotyčný mohl ovládat herní server který je s webem propojený.

Majkl578:
tím, že jsi tu uvedl implementaci tvého šifrování, přestává platit tvůj předpoklad
Ovšem. Stačí však změnit pořadí znaků v $this->chr + přidat tam nějaké znaky navíc a už je výsledek úplně jiný. :)

Cokoliv jde zakódovat a znovu rozkódovat v žádném případě nejde považovat za hash
Však já se opravil ;)

Nikomu mou funkci nevnucuji. Mně se líbí, zatím mě nijak nezklamala. Až zklame, přejdu na AES, o kterém jsem doposud nevěděl (kdyby ano, asi bych tuto funkci ani nevytvářel).
Ugo
Profil
1Pupik1989:
by ses divil jak často se to hodí, v některých případech musíš i ty hesla mít možnost rozlouskat zpátky, ale přitom je mít co nejbezpečnější pro případ např. vykradení db. Naposled sem nějaký to zašifrování použil u přihlašování přes get, jen už si nějak nepamatuju proč nešel použít hash :D, osobně tedy používám okořeněnou klasiku (nevim název) ord(string)+ord(key), jelikož není tajná:

public function crypt($input,$key) {
    $input=utf8_decode($input);
    $key_len=strlen($key);
    $i2=0;
    $string="";
    for($i=0;$i<strlen($input);$i++) {
        if($i2>=$key_len) $i2=0;
        $tmp=str_replace("0",chr(rand(71,96)),sprintf("%03s",dechex(ord($input[$i])+ord($key[$i2]))));
        $string.=$tmp;
        $i2++;
    }
    return base64_encode($string);
}

public function decrypt($input,$key) {
    $input=base64_decode($input);
    $input=preg_replace("#[^0-9abcdef]#","0",$input);
    $string="";
    $key_len=strlen($key);
    $i2=0;
    for($i=0;$i<strlen($input);$i=$i+3) {
        if($i2>=$key_len) $i2=0;
        $tmp=hexdec(substr($input,$i,3));
        $tmp=$tmp-ord($key[$i2]);
        $string.=chr($tmp);
        $i2++;
    }
    return utf8_decode($string);
}

to vylepšení je v podstatě neznatelný, jen na první pohled vlastně generuje pokaždý jiný string
1Pupik1989
Profil
Za celou dobu, co píši v PHP jsem nikdy nepotřeboval vědět něčí heslo. Navíc web který to dělá je nedůvěryhodný.
Ugo
Profil
Bylo to potřeba na jednom velkym projektu, nelíbilo se mi to, ale zadání to prostě vyžadovalo. Mimo jiné cíl toho projektu podle mě je i sběr citlivých informací. Sou web. aplikace kde se to prostě nedá rozumně udělat jinak, všerůzný nadstavby nad emailama, icq, xmpp a další. Když musíš toho uživatele pod účtem k tvojí aplikaci přihlásit k ostatním jeho službám, ostatně i takovej FB klíč je vlastně heslo, i když snad zabezpečené proti využití jinde, ovšem když hackneš web, tak ho můžeš použít jak nic.

btw. několikrát jsem viděl zmínku, že md5 jde rozlousknout (nejspíš najít jednu z možných shod), nevím zda je to pravda nebo tím je na mysli ten web který má databázi klíčů. nevíte někdo víc?
Keeehi
Profil
Ugo:
U md5 byl objeven postup, jak vytvořit řetězec aby jeho hash odpovídal námi vybranému. Tyto řetězce jsou ale extra dlouhé, takže pokud má aplikace omezenou délku hesla třeba na 30 znaků je i tento postup ze hry a musí se to dělat jako u jiných funkcí.

Je to však stará informace a nejsem si jistý, jestli si to pamatuji správně.
Majkl578
Profil
Ugo:
několikrát jsem viděl zmínku, že md5 jde rozlousknout
Nejde. Je to jednosměrný hashovací algoritmus.

Keeehi:
U md5 byl objeven postup, jak vytvořit řetězec aby jeho hash odpovídal námi vybranému.
To není žádná převratná novinka. Každý hash má nějakou velikost, která určuje jeho sílu. MD5 má velikost 128 bitů což dává 2^128 (3.4*10^38) možných variant výstupu, je proto méně odolný vůči narozeninovému útoku.
Ugo
Profil
Majkl578:
samozřejmě jsem neměl na mysli dostat 100% vstupní string, to je vlastně nemožné právě protože je možnost duplicit, myslel jsem jestli není možné najít ten první shodný, což by většinou byl právě ten původní, ale občas je jedno jestli máš string dlouhej 5 nebo úplně jinej s délkou 5000 jehož výsledek je stejnej. Rozdíl je jen v tom že když se to prolomí jinym vstupem, tak stále nevím jaké má uživatel heslo, který může používat i jinde.
Someone
Profil
Tato problematika je vskutku zajímavá, tudíž bych se rád zeptal. Když si hashuju string na localhostu (řekněme pomocí MD5) tak se to přeci zpracovává u mě na PC, tudíž mám přístup ke všem souborům, které zajišťují ono šifrování. Jak je možné, že se nikomu zatím nepodařilo rrozlousknout MD5 popř SHA1 ? To je to napsané tak "nečitelně". V čem je háček?
Keeehi
Profil
Someone:
Algoritmus hashování není tajný. Problém je v tom, že při hashování se ztrácí informace. Z nekonečného množství vstupů se vytváří konečné množství kombinací (u MD5 2^128) tudíž některé informace jsou zahozeny. Takže i když znáš postup, jakým se to zpracovávalo, nejsi schopný to zpětně rekonstruovat.

Zjednodušený a ne úplně přesný příklad:
hash($vstup) {
    return ((($vstup/10)%10)*(($vstup)%10))%10
} // funkce vezme poslední 2 cifry vstupu, ty mezi sebou pronásobí a vrátí jejich poslední cifru

hash nějakého čísla není problém spočítat
hash(4864) == 4
z 4 ale číslo 4864 nezrekonstruuješ, protože se informace ztrácejí (to dělá to modulo).

Majkl578:
Měl jsem na mysli toto: http://www.root.cz/clanky/tunely-v-hasovacich-funkcich-kolize-md5-do-minuty/
Ne že bych tomu nějak extra rozuměl, ale pokud se nepletu tak existuje matematický "předpis" rovnic které se jen vypočítají.
Alphard
Profil
[#27] Someone
Stačí matematika. Mám tady rozepsaný jednodušší příklad.

Mám heslo, které se skládá ze dvou čísel (znaků), následně obě čísla sečtu a výsledek označím za hash.
function hash($pass) return $pass[0]+$pass[1];

Znáš algoritmus, hash mého hesla je 12, jaké je moje heslo?
Someone
Profil
Alphard, Keeehi:
děkuju za vysvětlení :)
« 1 2 »

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: