PHP i OpenSSL

PHP i OpenSSL

offline
  • Pridružio: 02 Jan 2008
  • Poruke: 2167

Pokusavam da napravim portal za razmenu sifrovanih poruka koristeci asimetricno sifrovanje. Citao sam i koliko vidim, OpenSSL dodaci za PHP su jedino dobro resenje.

E sad, problem nastaje jer ja iz nekog razloga ne mogu da generisem kljuceve gledajuci ovaj primer:
//kreiranje privatnog i javnog kljuca za Boba $key = openssl_pkey_new(array('private_key_bits' => 2048)); $bob_key = openssl_pkey_get_details($key); $bob_public_key = $bob_key['key']; //Alisa salje poruku koju sifruje Bobovim javnim kljucem $alice_msg = "Hi Bob, im sending you a private message"; openssl_public_encrypt($alice_msg, $pvt_msg, $bob_public_key); //Bob prima Alisinu poruku i koristi svoj privatni kljuc za desifrovanje openssl_private_decrypt( $pvt_msg, $bob_received_msg, $key); print $bob_received_msg;

Moje pitanje je, da li je meni potreban SSL sertifikat da bi mogao da generisem privatne i javne kljuceve koristeci kod iznad? Iskoristio bih Let's encrypt recimo, posto je besplatan.

Pokusao sam prvi primer ovde, pa da izgenerisem svoje serftifikate, ali neuspeva :
+ Greska
+ Kod

Konkretno mi je namera da se prilikom svake registracije novog korisnika kreira njegov privati i javni kljuc i da se oni odmah upisu u bazu (znam da nije bas najbolja praksa, ali ovo je projekat za vezbu). Nakon toga, ja bih koristio te kljuceve za sifrovanje/desifrovanje poruka izmedju korisnika.



Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
offline
  • Peca  Male
  • Glavni Administrator
  • Predrag Damnjanović
  • SysAdmin i programer
  • Pridružio: 17 Apr 2003
  • Poruke: 23211
  • Gde živiš: Niš

Napisano: 18 Jun 2017 17:33

Možda je banalan problem - možda PHP na Windowsu nije podešen da radi sa OpenSSL.
Digni Linux na virtuelnoj mašini pa probaj isti taj kod.

Dopuna: 18 Jun 2017 17:38

btw, signed sertifikat ti svakako nije potreban... radio sam sa tim OpenSSL PHP funkcijama sa sertifikatom koji sam sam izgenerisao na Linuxu.



offline
  • Milan
  • Pridružio: 17 Dec 2007
  • Poruke: 14824
  • Gde živiš: Niš

Napisano: 18 Jun 2017 17:51

Asinhrono šifrovanje? Misliš asimetrično?

Dopuna: 18 Jun 2017 17:53

I druga stvar, kako bi te poruke između korisnika bile obezbeđene na putu do servera? Kroz HTTPS konekciju?

offline
  • Pridružio: 02 Jan 2008
  • Poruke: 2167

Napisano: 18 Jun 2017 18:53

Peca ::Napisano: 18 Jun 2017 17:33

Možda je banalan problem - možda PHP na Windowsu nije podešen da radi sa OpenSSL.
Digni Linux na virtuelnoj mašini pa probaj isti taj kod.

Dopuna: 18 Jun 2017 17:38

btw, signed sertifikat ti svakako nije potreban... radio sam sa tim OpenSSL PHP funkcijama sa sertifikatom koji sam sam izgenerisao na Linuxu.


U php.ini fajlu sam skinuo ; sa openssl dodatka, tako da je sa te strane u redu. Ne znam da li je jos nesto potrebno podesavati?

Da li je kod sa php.net sajta koji sam gore okacio dovoljan za generisanje potrebnih sertifikata?

Da li bi ja uopste mogao da koristim Let's encrypt SSL sertifikat za OpenSSL? Pitam za slucaj da se spetljam sa Linuxom, jer ce mi onda biti lakse da dobijem vec gotov sertifikat nego da ga sam generisem.

vasa.93 ::Napisano: 18 Jun 2017 17:51

Asinhrono šifrovanje? Misliš asimetrično?

Dopuna: 18 Jun 2017 17:53

I druga stvar, kako bi te poruke između korisnika bile obezbeđene na putu do servera? Kroz HTTPS konekciju?


Lapsus, ispravljeno Mr. Green

Pa da, jer ne vidim drugi nacin za to. Preko HTTPS-a bi izbegao "man-in-the-middle attack" napade. Za to sam svakako planirao Let's encrypt SSL da ubacim...

Dopuna: 19 Jun 2017 21:00

Izgleda da je problem ipak bio jer radim na lokalu. Kad sam kod ispod pokrenuo na shared hostingu, dobio sam odgovor bez greske.

+ Kod

Dopuna: 19 Jun 2017 22:52

Ok, sve sam osposobio i uspesno izgenerisem privatne i javne kljuceve koje potom upisem u bazu koristeci ovaj kod:

+ Kod

Ipak, sada mi je problem da poruku sifrujem i da je upisem u bazu, posto se u bazi upise prazno polje. Koristim ovaj kod:

<?php require 'provera_sesije.php'; require 'baza.php'; //Fetching Values from URL $poruka2=$_POST['poruka1']; $korisnik_forma2=$_POST['korisnik_forma1']; $javni_kljuc = ''; $sifrovana_poruka = '';             $sql = "SELECT javni_kljuc FROM bz.kljucevi WHERE korisnik='$korisnik_forma2'";       $result = $conn->query($sql);       if ($result->num_rows > 0) {           // output data of each row           while($row = $result->fetch_assoc()) {               /*$fff = $row['javni_kljuc'];               $javni_kljuc = openssl_get_publickey($fff);*/               $javni_kljuc = openssl_get_publickey($row['javni_kljuc']);              //pokusao sam i ovo, posto openssl_get_publickey() ocekuje kljuc u PEM formatu             /*            $aaa = openssl_pkey_export($row['javni_kljuc'],$fff);            $javni_kljuc = openssl_get_publickey($fff);*/           }       } else {           echo "Došlo je do greške...";       } openssl_seal($poruka2, $sifrovana_poruka, $ekeys, array($javni_kljuc)); //Insert query $stmt = $conn->prepare("INSERT INTO bz.poruke (poslao, primio, poruka) VALUES (?, ?, ?)"); $stmt->bind_param("sss", $_SESSION['email'], $korisnik_forma2, $sifrovana_poruka); $stmt->execute(); $stmt->close(); $conn->close(); openssl_free_key($javni_kljuc); ?>

Mene konkretno buni treci parametar funkcije openssl_seal() a to je promenljiva $ekeys. Gledam dokumentaciju ali ne vidim odakle je ta promenljiva i sta da joj dodelim kao vrednost... Moze li neko da pomogne?

offline
  • Milan
  • Pridružio: 17 Dec 2007
  • Poruke: 14824
  • Gde živiš: Niš

To je 'povratna' vrednost. Drugi i treći parametar se prenose po referenci, pa se oni setuju unutar same funkcije. Dakle, pored šifrovane poruke metoda vraća i niz ključeva kojima je ta poruka šifrovana, a ti ključevi su šifrovani javnim ključevima koji su prosleđeni. Dešifrovanje verovatno ide obrnuto - privatnim ključevima se najpre dešifruju ključevi, a onda se pomoću dešifrovanih ključeva dešifruje poruka. Na osnovu ovoga lako je zaključiti da pored šifrovane poruke moraš da pamtiš i taj niz šifrovanih ključeva.

offline
  • Peca  Male
  • Glavni Administrator
  • Predrag Damnjanović
  • SysAdmin i programer
  • Pridružio: 17 Apr 2003
  • Poruke: 23211
  • Gde živiš: Niš

return void :: Izgleda da je problem ipak bio jer radim na lokalu. Kad sam kod ispod pokrenuo na shared hostingu, dobio sam odgovor bez greske.
Rekoh ja...

offline
  • Pridružio: 02 Jan 2008
  • Poruke: 2167

Na kraju sam odustao od upisivanja kljuceva u bazu jer nikako nisam uspeo da ih izvucem. Zato sam uradio ovako i pamtim ih kao fajlove:

<?php require 'provera_sesije.php'; require 'baza.php'; //Fetching Values from URL $poruka2=$_POST['poruka1']; $korisnik_forma2=$_POST['korisnik_forma1']; // Compress the data to be sent $poruka2 = gzcompress($poruka2);   // Get the public Key of the recipient $publicKey = openssl_pkey_get_public('file://kljucevi/'.$korisnik_forma2.'/public.key'); $a_key = openssl_pkey_get_details($publicKey);   // Encrypt the data in small chunks and then combine and send it. $chunkSize = ceil($a_key['bits'] / 8) - 11; $output = '';   while ($poruka2) {     $chunk = substr($poruka2, 0, $chunkSize);     $poruka2 = substr($poruka2, $chunkSize);     $encrypted = '';     if (!openssl_public_encrypt($chunk, $encrypted, $publicKey))     {         die('Failed to encrypt data');     }     $output .= $encrypted; } openssl_free_key($publicKey);   // This is the final encrypted data to be sent to the recipient $encrypted = $output; base64_encode($encrypted); //zbog BLOB-a //Insert query $stmt = $conn->prepare("INSERT INTO bz.poruke (poslao, primio, poruka) VALUES (?, ?, ?)"); $stmt->bind_param("sss", $_SESSION['email'], $korisnik_forma2, $encrypted); $stmt->execute(); $stmt->close(); $conn->close(); ?>

Ipak, kad sada pokusam da desifrujem poruku, nikako ne uspevam.

Ovo je kod za desifrovanje za korisnika koji poruku prima. Isti kod je i za korisnika koji poruku salje, samo se razlikuju parametri za query:

//$_SESSION['email'] je trenutno ulogovani korisnik tj. onaj ko poruku cita (desifruje) $sql2 = "SELECT poslao, primio, poruka, vreme FROM bz.poruke WHERE poslao='".$_SESSION['korisnik']."' AND primio='".$_SESSION['email']."' ORDER BY vreme DESC"; $result2 = $conn->query($sql2); if ($result2->num_rows > 0) { // output data of each row while($row2 = $result2->fetch_assoc()) { // Get the private Key if (!$privateKey = openssl_pkey_get_private('file://kljucevi/'.$_SESSION['email'].'/private.key')) { die('Private Key failed'); } $a_key = openssl_pkey_get_details($privateKey);                                                               // Decrypt the data in the small chunks $chunkSize = ceil($a_key['bits'] / 8); $output = ''; base64_decode($row2['poruka']); //zbog BLOB-a $sifrovano = $row2['poruka']; while ($sifrovano) { $chunk = substr($sifrovano, 0, $chunkSize); $sifrovano = substr($sifrovano, $chunkSize); $decrypted = ''; if (!openssl_private_decrypt($chunk, $decrypted, $privateKey)) { die('Failed to decrypt data'); } $output .= $decrypted; } openssl_free_key($privateKey);                                                               // Uncompress the unencrypted data. $output = gzuncompress($output);                                                             echo ''.$output.''; echo '<br />'; echo '<small class="text-muted">'.$row2['poslao'].' | '.$row2['vreme'].'</small>'; echo '<hr />';

Gde gresim? Neutral

Ko je trenutno na forumu
 

Ukupno su 840 korisnika na forumu :: 7 registrovanih, 0 sakrivenih i 833 gosta   ::   [ Administrator ] [ Supermoderator ] [ Moderator ] :: Detaljnije

Najviše korisnika na forumu ikad bilo je 3466 - dana 01 Jun 2021 17:07

Korisnici koji su trenutno na forumu:
Korisnici trenutno na forumu: branko7, cikadeda, Istman, Japidson, kybonacci, repac, WerWolf14