Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Mcrypt funktion sisällä

Sivun loppuun

pistemies [27.07.2011 14:17:55]

#

Mikhän täsä on vikana kun ei toimi.

 function string_crypt($str,$key,$crypt){
     /* Merkkijonon salaus */
    $ivk = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);    // haetaan IV:n koko
    $iv = mcrypt_create_iv($ivk, MCRYPT_RAND);            // luodaan uusi IV

		if($crypt == "encrypt"){
					$string = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $str, "cbc", $iv);
					return $string;
		}
		if($crypt == "decrypt"){
					// puretaan salaus oikealla avaimella
					$string = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $str, "cbc", $iv);
					return trim($string);
		}
  }

Salaus toimii jotenkin (en tiedä, toimiiko oikein), purku ei lainkaan.

Mod. korjasi oikeat kooditagit.

Metabolix [27.07.2011 14:44:44]

#

No ei se tietenkään toimi, kun käytät salauksessa ja purkamisessa eri IV:tä. IV pitää toimittaa salatun datan mukana, tai pitää olla jokin keino luoda aina sama IV. Yksi purkkaratkaisu on muodostaa IV itse vaikka avaimesta.

$iv = substr(str_repeat(md5($key, 1), 1 + $ivk / 16), 0, $ivk);

pistemies [27.07.2011 15:26:42]

#

Metabolix kirjoitti:

No ei se tietenkään toimi, kun käytät salauksessa ja purkamisessa eri IV:tä. IV pitää toimittaa salatun datan mukana, tai pitää olla jokin keino luoda aina sama IV.

Empä tajua oikeen tuosta mitään.
Yleensähän salaus ja salauksen purku tapahtuu toisistaan erillään, jopa eri nettisivulla.

Katos.... olet muokannu just ikään tota hommaa...
Ekassa oli se homma oikein, kun kaikki oli samassa php-tiedostossa, purki oikein.
Tallennan kuitenkin salauksen mysql-kantaan.
Kun yritän purkaa sieltä, tulee pelkkää sotkua.

Onko normaali string-tyyppi riittävä tietokannan sarakkeen tyypiksi..?
Kokeilen tässä kohta tuota uutta.

Ps. Sama ongelma on tässä esimerkissäkin, tulostaa tietokannasta pelkkää sotkua. Toimii, jos salaus ja purku on samassa paketissa, kuten putkan ohjeessa (mutta niinhän ei yleensä ole).

Metabolix [27.07.2011 15:37:06]

#

Muokkasin viestistäni toteutustapaa, mutta asia ei siitä miksikään muutu: IV vaaditaan CBC:n purkuun, ja väärä IV tuottaa väärän purkutuloksen.

Tietokannassa binaaridatalle kannattaa käyttää binaaridatatyyppejä (CHAR -> BINARY, VARCHAR -> VARBINARY ja TEXT -> BLOB). Tavallisilla tekstityypeillä data voi mennä sekaisin, erityisesti, jos UTF-8 on jossain välissä mukana.

pistemies [27.07.2011 16:13:00]

#

Yhä on sama ongelma purkamisessa.
Olen kokeillut "tyyppejä" BINARY ja VARBINARY.
Tietokanta on normaalintapaan utf8-muodossa. Ja sivut, joilla tietokannasta luetaan, on myös utf8 mukana.

timoh [27.07.2011 16:14:22]

#

Kun käytät CBC-moodia, turvallisin ja simppelein tapa luoda IV on käyttää satunnaislukugeneraattoria. Metabolixin yllä esittämä tapa ei luultavasti täytä IV:n vaatimuksia (tietoturvan kannalta).

Käytännössä pyydät satunnaislukugeneraattorilta tarvittavan määrän tavuja ja käytät tätä bytestringiä IV:nä. Tämän saman bytestringin sitten konkatenoit esim. ciphertekstin alkuun (jotta voit salausta purkaessa poimia tämän IV:n ja käyttää sitä).

Sitten muutama muu huomio. Onko jokin syy käyttää juuri Blowfishia (eikä AES:ia)?

Ja toinen oleellinen kohta on että koodissasi ei käy ilmi autentikoitko ciphertekstiä ollenkaan? Jos et, niin CBC-moodin kanssa sinun täytyy tehdä autentikointi manuaalisesti (HMAC-SHA-256). Eli lasket koko pötköstä HMACin (omalla avaimellaan) ja liität sen myös ciphertekstin alkuun (jotta voit sitten purkaessa verrata täsmääkö HMAC). Tämän HMACin tulee sisältää kaikki materiaali, myös IV. Eli ns. "encrypt-then-mac approach".

Meitzi [27.07.2011 16:19:30]

#

Toimiihan Metabolixen ohjeen mukaan, kun teet sekä salauksen että purun tuolla "kiinteällä" IV:llä. (eli turhaan kokeilet jos et salaa uudestaan)

pistemies [27.07.2011 16:23:39]

#

Tuo ylläoleva funktio on ainoa, missä salaukseen vaikutetaan, sen ulkopuolella vain käyetään perusdataa salaamiseen ja purkuun.
Olen tätä koko mcrypt-salausta eka-kertaa nyt käyttämässä. Tuota enempää ohjeita ei putkan ohjeissa ollut tästä.
Nuo muut toiminnot, autentikointi ja ciphar on minulle vielä vieraita käsitteitä.
Olen hiukan vilkaissut php.netin sivuilta, mutta englannin kieli ei taivu ja skripti-esimerkit ei oikein sano siellä tarpeeksi... ainakaan näin alkuun.

lainaus:

Toimiihan Metabolixen ohjeen mukaan, kun teet sekä salauksen että purun tuolla "kiinteällä" IV:llä. (eli turhaan kokeilet jos et salaa uudestaan)

Salaa uudestaan?

$nimi = $mysqlrow['nimi'];
$purku = string_crypt($nimi,$key,"decrypt");
echo $purku;
// ei tomi

Näin minulla on.

Metabolix [27.07.2011 16:30:43]

#

timoh kirjoitti:

Metabolixin yllä esittämä tapa ei luultavasti täytä IV:n vaatimuksia (tietoturvan kannalta).

IV on joka tapauksessa salaamatonta dataa ja usein välitetäänkin viestin mukana sellaisenaan. Sen tietoturvalla ei ole mitään väliä.

Tietenkään avaimesta muodostettua IV:tä ei kannata välittää viestin mukana, koska joku voisi murtaa sen perusteella avaimen, mutta koko idean tausta olikin, että noin IV:tä ei tarvitse tallentaa mihinkään.

Pekka Mansikka kirjoitti:

Yhä on sama ongelma purkamisessa.

Onko se debuggaaminen niin mahdottoman vaikeaa? Oletko edes vaivautunut katsomaan, tuleeko tietokannasta sama tieto, jonka sinne laitat? Entä mistä $key tulee, onko sekään enää sama?

timoh [27.07.2011 16:39:27]

#

Voi olla että pääset helpoimmalla käyttämällä tätä:
https://github.com/timoh6/TCrypto

Tuo ei aivan suoraan ole sitä mitä haet, mutta kirjoittamalla sopivan "StorageHandlerin" (mikä siis tallentaa datan tietokantaan sinun tapauksessasi), saat tehtyä homman jo melko pitkälle. "Käyttöliittymä" ja mm. tietoturvanäkökohdat on mietitty valmiiksi, joten niihin ei tarvitse kiinnittää erityishuomiota (salatun datan käsittely jne).

Jos et halua suoraan tuota käyttää, voit toki katsoa esimerkkiä suoraan koodista.

EDIT: En päässyt uutta viestiä enää kirjoittamaan, mutta editoin tähän kommenttia tuosta Metabolixin kommentista:

"IV on joka tapauksessa salaamatonta dataa ja usein välitetäänkin viestin mukana sellaisenaan. Sen tietoturvalla ei ole mitään väliä."

En ole ihan varma mitä Metabolix ajoi tuolla "Sen tietoturvalla ei ole mitään väliä" takaa, mutta selvennän sen verran, että CBC-moodin kanssa IV ei saa toistua. Pekan tapauksessa luultavasti ainoa mahdollinen vaihtoehto IV:n luomiseksi on juuri tämä "Random IV". Muuten avautuu erilaisia mahdollisuuksia hyökätä salausta vastaan.

pistemies [27.07.2011 17:03:51]

#

Metabolix kirjoitti:

IV on joka tapauksessa salaamatonta dataa ja usein välitetäänkin viestin mukana
Onko se debuggaaminen niin mahdottoman vaikeaa? Oletko edes vaivautunut katsomaan, tuleeko tietokannasta sama tieto, jonka sinne laitat? Entä mistä $key tulee, ja onhan se molemmilla kerroilla sama?

Kerrassaan hyvä neuvo :)
Sain sen nyt tomimaan.
Yksi asia vielä...onko tietoa, miten pitkää dataa mcrypt-funktiolla pystyy salaamaan? Voi olla tarvetta pitemmillekkin teksteille...

Metabolix [27.07.2011 17:16:32]

#

timoh: Puhuit IV:n tietoturvasta, jolloin syntyi kuva, että IV:n paljastuminen olisi suuri vaara. Näinhän ei kaiketi ole?

timoh kirjoitti:

CBC-moodin kanssa IV ei saa toistua

Totta, lähdin oletuksesta, että joka salauksessa olisi eri avain.

Eli IV:n osalta korjattuna alkuperäinen funktio voisi siis toimia näin:

function string_crypt($str, $key, $encrypt = true) {
    $ivk = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
    if ($encrypt) {
        $iv = mcrypt_create_iv($ivk, MCRYPT_DEV_URANDOM);
        return $iv.mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $str, "cbc", $iv);
    } else {
        $iv = substr($str, 0, $ivk);
        $str = substr($str, $ivk);
        return mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $str, "cbc", $iv);
    }
}

Pekalle vinkkinä: Epämääräisten tekstien käyttö on altis virheille. Kun vaihtoehtoja on kaksi, true tai false sopii hyvin. Jos vaihtoehtoja on enemmän, niistä voi tehdä vakioita (definellä tai luokkiin constilla). Aina on parempi saada kirjoitusvirheestä virheilmoitus kuin väärä tulos.

pistemies [27.07.2011 17:47:16]

#

Kiitos vinkistä.

Uutta "väärää tulosta" pukkaa.
Datan käsitteleminen tulostettaessa heittää mäkeen.
Siis tämän tyyppistä minulla on:

$haku1 = "[img]";
       $haku2 = "[/img]";

	    $haku1_pos = strpos($tekstit, $haku1);
	    $haku2_pos = strpos($tekstit, $haku2);

			 if($haku1_pos > 0){
			    $sisalto = substr($tekstit, $haku1_pos + strlen($haku1), $haku2_pos - $haku1_pos - strlen($haku1));

	                # tarkista kuvan koko
	                if($sisalto !=''){
	                  $tekstit = image_replace($sisalto,$tekstit);
	                }
          }

Tämä näyttäisi aiheuttavan oudon virheen tulostuksessa. Siihen ei vaikuta se, tulostetaanko tuolta image_replace-funktion kautta vai ei. Se tarkistaa lisätyn kuvan leveyden, jos se on leveämpi kuin maximi (esim. 400), se näyttää kuvan pienempänä tyyliin width="400".
Muut muotoilut, replacet, tuo näyttää hyväksyvän.

Metabolix [27.07.2011 18:09:39]

#

Sitten ei varmaan auta kuin googlettaa hakusanalla "outo virhe" ja katsoa, mitä löytyy. (Huonoon kysymykseen huono vastaus.)

timoh [27.07.2011 18:31:27]

#

IV:n paljastuminen ei tosiaan ole haitallista. Mutta IV:n täytyy olla "kryptorandom".

Tuohon Metabolixin koodiin tulisi muuttaa MCRYPT_DEV_URANDOM käytettäväksi satunnaisuuden lähteeksi (mcrypt_create_iv:hen). Myös autentikaatio on kriittinen lisättävä (muuten lähtökohtaisesti salaus voidaan purkaa tietämättä avainta).

pistemies [27.07.2011 18:34:40]

#

Niimpä.
Eipä tässä näytä tomivan normaali muotoilukaan.

$tekstit = string_crypt($row['tekstit'],"avain","decrypt");
 echo $tekstit;  // tulostaa oikein: [b]testi[/b]

$tekstit = preg_replace("/\[b\](.*?)\[\/b\]/i", "<b>$1</b>",$tekstit);

echo $tekstit; // tulostaa "t" lihavoituna

Ennen tätä salausta tulosti niinkuin pitikin.

Ps. Vika löytyi kun etsin rivi kerrallaan kommentti-merkkiä käyttäen. Vika johtui tästä rivistä, kun lisäsin siihen if-lauseen, se sitten toimi kunnolla

if($taustakuva !=''){
  $tekstit = str_replace($taustakuva,"",$tekstit);
}

Metabolix [27.07.2011 19:09:21]

#

Eiköhän vika ole nyt tuolin ja näppäimistön välissä. Ei toisen funktion toiminta riipu siitä, mistä syötettävä data on peräisin. Jos data on oikein, myös korvaus toimii oikein.

Edit: Myöskään esittämäsi korjaus ei selitä mitään: str_replace("","",$teksti) ei muuta tekstiä mihinkään suuntaan, joten if-lause on turha.

timoh kirjoitti:

Myös autentikaatio on kriittinen lisättävä (muuten lähtökohtaisesti salaus voidaan purkaa tietämättä avainta).

Mistä autentikaatiosta nyt puhut, ja millainen salaus sinusta "voidaan lähtökohtaisesti purkaa tietämättä avainta"? Minusta salauksen lähtökohtana on aina, että purkaminen ei käytännöllisesti onnistu ilman avainta ja että avaimen selvittäminen on suhteellisen hankalaa, vaikka tunnettaisiin osia salaamattomastakin datasta. Eihän salauksessa olisi mitään järkeä, jos sen voisi tuosta vain purkaa.

pistemies [27.07.2011 19:20:22]

#

Metabolix kirjoitti:

Edit: Myöskään esittämäsi korjaus ei selitä mitään: str_replace("","",$teksti) ei muuta tekstiä mihinkään suuntaan, joten if-lause on turha.

Niin se näin teoriassa pitäisi tietysti toimia. Mutta kun se if-lause minulla siinä on, se tulostaa "testi" lihavoituna, ilman sitä tulostaa "t" -lihavoituna, kuten jo edellisessä viestissäni kerroin.
Kun vikaa etsin, laitoin sen rivin eteen kommennti-merkin #, ja kas, sehän toimi oikein. Siitä päätellen vika oli juuri siinä.

Metabolix [27.07.2011 19:57:41]

#

Katsopa vielä esim. urlencode-funktion avulla muuttujien sisällöt ennen ja jälkeen tuon rivin. Jos vaikka jokin ihmeellisempi vika löytyisi.

pistemies [27.07.2011 20:12:35]

#

Joo. Peruutan puhettani. Sen jälkeen kun olin laittanut sen if-lauseen, korjasin myös tätä

if($tyyli1_pos == 0 && $tyyli2_pos > 0){
$taustakuva = substr($tekstit, $tyyli1_pos + strlen($tyyli1), $tyyli2_pos - $tyyli1_pos - strlen($tyyli1));
// laitetaan taustakuva muuttujaan....
..
}

Minulla oli tuo alkuaan vain $tyyli1_pos, ja sehän on aina nolla vaikka siihen liittyvää muotoilua (tageja + taustakuvan url-osoitetta) ei olisikaan kirjoitettu "viestiin".
Tuo yritti turhaan hakea sitä kuvatietoa viestistä substr-funktiolla...

timoh [27.07.2011 21:54:43]

#

Metabolix kirjoitti:

Mistä autentikaatiosta nyt puhut, ja millainen salaus sinusta "voidaan lähtökohtaisesti purkaa tietämättä avainta"? Minusta salauksen lähtökohtana on aina, että purkaminen ei käytännöllisesti onnistu ilman avainta ja että avaimen selvittäminen on suhteellisen hankalaa, vaikka tunnettaisiin osia salaamattomastakin datasta. Eihän salauksessa olisi mitään järkeä, jos sen voisi tuosta vain purkaa.

Autentikaatiolla tarkoitan tuota mainitsemaani HMACia, mikä lasketaan, omalla avaimellaan, salatusta tekstistä (sisältäen IV:n). Jos salattua tekstiä on manipuloitu, tämä huomataan kun vertaillaan HMACeja, eikä hyökkääjän muokkaamaa dataa ikinä viedä decryptattavaksi.

Tuossa salauksen purkamisessa minkä mainitsin (tietämättä avainta) on kysymyksessä "padding oracle attack". Tämä aiheutuu CBC-moodista. Käytännössä CBC-moodia käytettäessä on huolehdittava aina myös datan autentikoinnista (ei ole syytä ottaa riskiä että padding oraclen tjms. mahdollisuus ei olisi systeemissä).

Salauksen lähtökohta on aina juuri tuo mitä mainitsit, mutta "salausoperaatio" täytyy implementoida oikein jotta homma pelaa niin kuin pitää (tämä ei välttämättä ole niin triviaalia kuin voisi äkkiseltään olettaa).

pistemies [27.07.2011 23:11:02]

#

timoh kirjoitti:

Voi olla että pääset helpoimmalla käyttämällä tätä:
https://github.com/timoh6/TCrypto

Aina kannattaa hiukan mainostaa :)
Laitoin tuon linkin talteen... ehkä joskus testailen tuotakin.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta