Autor Zpráva
xlifer
Profil
Potřebuji ukládat heslo do databáze tak, aby jej bylo možné zpětně dekódovat a přečíst. Vím, že to není ideální způsob, ale zkátka to tak potřebuji udělat.

Chtěl jsem použit funkci base64_decode/encode, ale zde chybí možnost použít pro en(de)kodování vlastní klíč, resp. klíč pomocí kterého heslo zašifruji a uložím, ale následně podle kterého taky přes klíč znovu přečtu. Pokud neznám klíč, tak heslo nepřečtu.

Samozřejmě, že to lze prolomit jako dnes vše, ale vzhledem k tomu, že nejde o banku, tak to neřeším na tak vysoké úrovni.

Potřeboval bych tedy poradit co by šlo použit v PHP za funkci na popsaný způsob ukládání a zpětně přečtení hesel. Napadlo mě si napsat něco vlastního, ale určite bude už něco na vyské úrovni připravené a možné používat...

Zhrnuto: Jak lze uložit heslo s vlastním otiskem, které lze zpětne přečíst, když znám otisk?

Diky za rady.
Medvídek
Profil
xlifer:
Třeba http://cz2.php.net/mcrypt
Mohu vědět, k čemu potřebujete číst hesla? Pokud se opravdu jedná o hesla uživatelů, tak je to dost "neetické".
juriad
Profil
Z jakého důvodu potřebuješ rozšifrovánat hesla?
A co na to chudák Franta, který používá všude stejné heslo?
Jaký má vůbec význam šifrovat hesla; proč je neuložíš rovnou nešifrovaně?

Abych nebyl tak nekonstruktivní:
http://cz1.php.net/manual/en/mcrypt.examples.php
xlifer
Profil
Medvídek:

Nejedná se o uživatele, ale spíše o takový zápisník hesel a přístupů. Přirovnal bych to ke stejným aplikacím kam si můžete uložit různé své přihlašovací jména a hesla, aby jste je nezapoměl. Takže když pak používáte 20 služeb a všude máte nějaký přístup, tak si buď napíšete někam na papír a nebo uložíte do nějaké aplikace ve které lze údaje znovu přečíst, ale ne bez otisku. To stejné potřebuji vyřešit v php do databáze...
xlifer
Profil
Našel jsem toto a funguje to zdá se k plné spokojenosti, ale nevím jestli to není moc zastaralé řešení?
Je to vlastně co bylo doporučené výše, ale zdá se mi to jednoduší na použití přes ty připravené funkce.

http://blog.justin.kelly.org.au/simple-mcrypt-encrypt-decrypt-functions-for-p/

A tady ješte odkaz kde sehnat a kam nahrát .dll v Apache pro správné fungování funkce mCrypt:

http://stackoverflow.com/questions/5844035/where-can-i-find-the-official-libmcrypt-dll-and-php-mcrypt-dll-for-php-5-3-on

Třeba se bude někdy někomu hodit.
Joker
Profil
xlifer:
base64_encode/decode není šifrování.
Svým způsobem je to pravý opak šifrování, nemá za cíl data znečitelnit, ale naopak zajistit jejich čitelnost po přenosu. Použít to na zakódování hesla je nesmysl.

Jinak jedna možnost je mcrypt, viz výše, ale existuje spolehlivá a přitom úplně primitivní šifrovací funkce, a sice operátor XOR.
Ukázka:
function xor_text($text, $klic) {
  // Klíč kratší než text se zopakuje tolikrát, aby nebyl kratší
  while (strlen($klic) < strlen($text)) {
    $klic .= $klic;
  }
  
  $result = "";
  
  for ($i = 0; $i < strlen($text); $i++) {
    $charTxt = substr($text, $i, 1);
    $charKey = substr($klic, $i, 1);
    $result .= $charTxt ^ $charKey; // XOR
  }
  return $result;
}

Další výhoda je, že stejná funkce obstará i dešifrování, volání xor_text se zašifrovaným textem a původním klíčem vrátí původní text.
Naopak nevýhoda je, že výsledek XOR reprezentovaný jako řetězec budou vesměs různé divné znaky, v kódování UTF-8 bude výsledek nejspíš řada obdélníčků (ovšem reprezentujících různé znaky) a asi mohou vzniknout i v unicode neplatné znaky. Takže třeba vytisknout to moc nepůjde, leda to konvertovat třeba na hexadecimální čísla, podobně jako MD5.
Další nevýhoda je, že aby XOR byla neprolomitelná, vyžaduje unikátní klíč stejné délky jako je vstup.

Ale s tím klíčem bude obecně problém: Když heslo bude šifrované, musí někde být zabezpečeně uložený šifrovací klíč. No a když už mám zabezpečené místo pro uložení šifrovacího klíče, to už tam můžu rovnou mít uložené to heslo.
xlifer
Profil
Joker:

base64_encode/decode není šifrování.
Svým způsobem je to pravý opak šifrování, nemá za cíl data znečitelnit, ale naopak zajistit jejich čitelnost po přenosu. Použít to na zakódování hesla je nesmysl.


Ale tady: http://blog.justin.kelly.org.au/simple-mcrypt-encrypt-decrypt-functions-for-p/ přece není jen prosté base64_encode/decode ? Je tam použit otisk bez kterého nelze přečíst zpět původní text.

Ale s tím klíčem bude obecně problém: Když heslo bude šifrované, musí někde být zabezpečeně uložený šifrovací klíč. No a když už mám zabezpečené místo pro uložení šifrovacího klíče, to už tam můžu rovnou mít uložené to heslo.

Ano, s tím bude vždy problém, ale ja to myslím tak, že ten klíč nebude nikde uložen - otisk bude vždy nutné zadat jako bezpečnost pro uložení nebo zobrazení textu. Jasně, je to otravné, ale zvýší to zabezpečení, když vynechám další myšlenky, že stejně zadaním toho otisku už vznikne někde stopa pří přenosu dat, atd.

Jinak jedna možnost je mcrypt, viz výše, ale existuje spolehlivá a přitom úplně primitivní šifrovací funkce, a sice operátor XOR.

To vypadá dobře. A kdybych použil tuto XOR funkci, tak je "lepší" a bezpečnější na prolomení než výše uvedená funkce s toho blogu, když opět nebude otisk nikde uložen, ale bude se zadávat vždy pro požadovanou opreraci čtení nebo uložení?
Medvídek
Profil
xlifer:
otisk bude vždy nutné zadat jako bezpečnost pro uložení nebo zobrazení textu.
Já moc nechápu přínos této služby, mít uložené hesla abych si je nemusel pamatovat a přitom si muset pamatovat šifrovací klíč ke službě, která mi ty hesla zobrazí. Navíc co když ztratim šifrovací klíč? :)
xlifer
Profil
Medvídek:

Je mi to jasné, že to působí celé podivně, ale tento tajný klíč nebude používán denně, jen občas v případě potřeby náhlednout do databáze na nějaké záznamy, takže to není tak velký problém. Hlavně jde o to, že klíč nebude uložen přímo někde na serveru apod. V tom vidím právě docela zvýšení o level bezpečnosti, že musíte ten klíč znát, jinak je zkrátka smůla s tím se počítá... Když zapomenete, tak holt smůla, data jsou ztracena...

Mám pocit, že na stejném principu fungují všechny různé peněženky na ukládání hesel, protože tam když zapomente taky váš otisk, tak máte smůlu, ale je to ošetření dokonalé, protože nikdo nenajde uložen u služby i klíč.


Nicméně pořád mi vrtá hlavou ten XOR, ale nevím zda je v něčem lepší ten ty simple funkce co jsem uváděl z toho blogu ?
doyle
Profil *
xlifer:

Mcrypt je pokud vim, mnohem lepsi nez pouhy XOR.

Pro zajimavost sifrovani Rijndeal, ktere je konkretne pouzite v onom prikladu mcryptu, dela nekolik XORu na maticich obsahujici prvky sifrovane posloupnosti "nejak" naskladanymi v radcich/sloupcich (presne si to nepamatuju, kdyztak je na to nadhernej komix - http://www.moserware.com/2009/09/stick-figure-guide-to-advanced.html ;-).

Jinak sluzba podle mne nesmyslna neni, rika se tomu heslovnik a realizuji to programy jako napr. KeePass nebo KDE Wallet, ale po netu bych tomu ja asi neveril, navic tyhle programy umoznuji sifrovat heslem a certifikatem, co uz by znelo trochu lip (viz napr. RSA a http://www.php.net/manual/en/function.openssl-public-encrypt.php)


Akorat jeste koukam ze ten priklad z http://blog.justin.kelly.org.au/simple-mcrypt-encrypt-decrypt-functions-for-p/ je trochu spatne, pro rezim sifrovani MCRYPT_MODE_ECB bude fungovat, protoze ten nepotrebuje iv(instruction vector), pokud pouzijes jiny rezim, jako MCRYPT_MODE_CBC (ktery je ostatne asi bezpecnejsi), tak musis pouzit pri desifrovani stejne iv jako pri sifrovani a ne ho generovat nahodne - coz dela volani mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND))
xlifer
Profil
doyle:
Jinak sluzba podle mne nesmyslna neni, rika se tomu heslovnik a realizuji to programy jako napr. KeePass nebo KDE Wallet, ale po netu bych tomu ja asi neveril, navic tyhle programy umoznuji sifrovat heslem a certifikatem, co uz by znelo trochu lip (viz napr. RSA a http://www.php.net/manual/en/function.openssl-public-encrypt.php)

Díky za názor, popis a hlavně TIP na funkci OpenSSL_Public_Encrypt(); to mě velmi zaujalo a abych se přiznal, tak tento způsob s použitím certifikátu neznám. To bych mohl použít namísto všech už zmíněných a probraných možností, ale nevím jak je to s tím certifikátem - kde ho mám vzít nebo vygenerovat?
Joker
Profil
xlifer:
Nicméně pořád mi vrtá hlavou ten XOR, ale nevím zda je v něčem lepší
Jestli je k dispozici nějaká knihovna, použil bych tu. Je lepší používat něco ověřeného, než vymýšlet svoje.
xlifer
Profil
Joker:
Souhlasím. Chtěl bych použít ten openssl-public-encrypt, ale nevím jak s tím certifikátem?
doyle
Profil *
xlifer:
OpenSSL_Public_Encrypt(); to mě velmi zaujalo a abych se přiznal, tak tento způsob s použitím certifikátu neznám. To bych mohl použít namísto všech už zmíněných a probraných možností, ale nevím jak je to s tím certifikátem - kde ho mám vzít nebo vygenerovat?

Problém s asymetrickým šifrováním je(viz Wiki), že bys měl poslat veřejný klíč serveru a privátní si nechat u sebe, ale na to bys potřeboval něco chytřejšího, co při příchodu odpovědi ze serveru provede ještě rozšifrování - buď nějaký prográmek nebo na linuxu klidně i menší skript. V tom prográmku můžeš provést request na server(který např. při registraci obdržel veřejný klíč uživatele) a po příchodu odpovědi obsahující heslo ji rozšifruješ privátní klíčem. Pokud bys posílal na serveru oba klíče(obě části certifikátu), tak si moc nepomůžeš. Generovat tyto certifikáty se dá např. pomocí ssh-keygen na win PuTTYgen.

Druhá možnost je použít symetrické šifrování, na to ti stačí uvedená funkce mcrypt a jako iv použít nějaký náhodně vygenerovaný soubor, který prohlásíš za certifikát. iv akorát vyžaduje aby měl pevně danou délku (viz mcrypt_enc_get_iv_size()) ke zkrácení certifikátu můžeš použít buď nějakou hashovací fci anebo si budeš rovnou generovat krátké certifikáty.


Za všech okolností by ale tato služba měla běžet na https s ověřeným certifikátem, pokud to má vůbec někdo rozumnej chtít používat.

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: