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.
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);
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).
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.
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.
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".
Toimiihan Metabolixen ohjeen mukaan, kun teet sekä salauksen että purun tuolla "kiinteällä" IV:llä. (eli turhaan kokeilet jos et salaa uudestaan)
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.
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?
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.
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...
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.
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.
Sitten ei varmaan auta kuin googlettaa hakusanalla "outo virhe" ja katsoa, mitä löytyy. (Huonoon kysymykseen huono vastaus.)
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).
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); }
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.
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ä.
Katsopa vielä esim. urlencode-funktion avulla muuttujien sisällöt ennen ja jälkeen tuon rivin. Jos vaikka jokin ihmeellisempi vika löytyisi.
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...
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).
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.
Aihe on jo aika vanha, joten et voi enää vastata siihen.