[PHP] Hoe het beste encryptie (E2E) toepassen?

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • HollowGamer
  • Registratie: Februari 2009
  • Niet online
Voor een project moet ik data syncen tussen meerdere endpoints. Die data wil ik beveiligen met een key, zodat enkel de clients deze kunnen uitlezen die dat mogen. Het is dus niet genoeg om deze enkel over TLS te versturen, ik moet het in de database versleuteld opslaan, en voorkomen dat andere erbij komen.

Nu heb ik zelf al met encryptie gewerkt, alleen is dit een stap verder. Gelukkig zijn er al tools beschikbaar:
- https://www.sitepoint.com...symmetric-keys-phpseclib/ (phpseclib)
- https://github.com/spatie/crypto

Alleen wat ik niet zo begrijp zijn de symmetric en asymmetric keys. Je hebt dus een Private+Public (async) en je hebt een random-key (sync). De Public-key (async) + de symmetric moet je geven aan de ontvanger, de Private-key + symmetric key gebruikt de verzender om het te versleutelen.. of toch niet?

Kan iemand het mij iets uitleggen? :)
Ter geruststelling, dit is iets waar ik zelf onderzoek naar doe, ik werk niet voor de overheid, en wil zelf leren hoe E2E veilig kan worden toegepast.

Thanks!

Alle reacties


Acties:
  • +4 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

De afkortingen voor asymmetric en symmetric zijn dus niet async en sync, want dat staat weer voor asynchronous en synchronous ;)

Bij een asymmetrische encryptie heb je twee sleutels die elkaars inverse zijn. Als je iets encrypt met de ene key, kun je het weer decrypten met de andere key. Je zou het kunnen zien als een slot waarbij je met de ene sleutel alleen linksom te draaien is, en met de andere sleutel alleen rechtsom, waarbij beide kanten het slot op slot doen en het slot alleen open is als hij precies in het midden staat.

Meestal wordt dit gebruikt in de vorm van een publieke en privé sleutel, waarbij je publieke sleutel gewoon gepubliceerd kan worden, terwijl alleen jij weet wat jouw privé-sleutel is.

Op die manier kan iemand dus een bericht die alleen door jou gelezen kan worden encrypten door jouw publieke sleutel te gebruiken. Andersom kun je het ook gebruiken als authenticatie: als je een bericht (of meestal een hash van een bericht) encrypt met jouw privé-sleutel, dan kan iedereen verifieren dat dat bericht ook echt van jou afkomstig is omdat het met jouw publieke sleutel te decrypten is.

Hier bovestaand verhaal als ikea-schema :P (links privacy, rechts authentication)

Afbeeldingslocatie: https://tweakers.net/i/YHL42eveyeaPFboO-vWGQNrDEbY=/800x/filters:strip_exif()/f/image/obwq9TkopH3COp7bbGsxka35.png?f=fotoalbum_large

Met een symmetrische sleutel gebruik je dezelfde sleutel voor zowel encryptie als decryptie. Dat is meer vergelijkbaar met een alledaags deurslot, waarbij je sleutel het slot zowel open als dicht kan doen. Dit betekent wel dat beide partijen moeten beschikken over dezelfde sleutel.

Waar verder vaak rekening mee wordt gehouden is performance: de operaties voor asymmetrische encryptie zijn over het algemeen een stuk duurder dan die voor symmetrische. Wat je typisch ziet is dat de asymmetrische encryptie alleen gebruikt wordt om een symmetrische sleutel te overhandigen. Als ik naar jou een geheim document wil sturen, kan ik het hele document met jouw publieke sleutel versleutelen, maar ik kan ook een willekeurige symmetrische sleutel genereren en het document daarmee versleutelen, en alleen die symmetrische sleutel met jouw publieke sleutel versleutelen. Alleen jij bent dan in staat om de symmetrische sleutel uit te lezen. Dit is vaak hoe het gaat met beveiligde verbindingen: het assymetrische gedeelte wordt alleen gebruikt voor de key exchange.




Nu even specifiek jouw probleem. Als ik het goed begrijp wil je berichten kunnen versturen naar meerdere mensen, maar daarbij wil je selectief kunnen zijn over wie specifieke berichten kunnen lezen. Conceptueel zou ik dan verwachten dat je de berichten versleutelt met tijdelijk gegenereerde symmetrische sleutels, waarbij je de sleutels aan de juiste partijen kunt overhandigen met behulp van asymmetrische encryptie.

Maar ik zou vooral ook eens goed kijken naar het E2EE Signal protocol wat door Signal en Whatsapp gebruikt wordt: https://signal.org/docs/specifications/doubleratchet/

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • HollowGamer
  • Registratie: Februari 2009
  • Niet online
@.oisyn Bedankt voor je uitgebreide uitleg en informatie. :)

De termen zijn inderdaad niet goed, ik wilde ze afkorten, maar gebruikte ze als JavaScript termen. 😅

Ik ben gaan lezen over sodium, en het ziet er naar uit dat dit het ideale library ervoor is. Het is gemaakt voor asymmetrisch, en ook symmetrische toepassing. In beide geven ze ook goede voorbeelden. Ben je het hiet mee eens? Of gebruiken de meeste iets anders? Ik kwam er achter dat de makers van sodium, ook een handige tool hebben om op encrypted data te zoeken. Voor berichten geven ze aan dat asymmetrisch mogelijk is, maar je kunt het zelfs ook een valid signed check doen, wat wel cool is als je API updates zou willen pushen.

Het E2EE van Signal zal ik eens checken. Het moet voor mij wel werken in PHP, aangezien ik Laravel gebruik als backend.

[ Voor 11% gewijzigd door HollowGamer op 18-06-2025 23:13 ]


Acties:
  • +2 Henk 'm!

  • dev10
  • Registratie: April 2005
  • Laatst online: 10:32
Je schrijft dat je data in de database versleuteld wilt opslaan en dat je gebruik maakt van Laravel. Met Laravel kun je vrij eenvoudig data versleuteld opslaan in de database met een encrypted cast: https://laravel.com/docs/...utators#encrypted-casting. Dit werkt out-of-the box zonder verdere configuratie.

Verder kun je sodium ook gebruiken met PHP (en dus met Laravel): https://www.php.net/manual/en/book.sodium.php. Hiermee kun je vrij eenvoudig een keypair maken bij je de public key verstrekt aan degene die de data moeten descrypten en gebruik je de private key om de data in de applicatie te encrypten.

De implementatie waarbij de zender en ontvanger beiden hun public keys met elkaar uitwisselen is daarbij ook vrij eenvoudig te maken. Zie daarvoor de functie: sodium_crypto_box_keypair_from_secretkey_and_publickey

[ Voor 4% gewijzigd door dev10 op 19-06-2025 09:15 ]


Acties:
  • +1 Henk 'm!

  • ValHallASW
  • Registratie: Februari 2003
  • Niet online
Wat is het risico dat je probeert te mitigeren? In andere woorden, op basis waarvan zeg je "ik moet het in de database versleuteld opslaan"?

Zolang je in je php-code alles kunt decrypten levert encrypted opslag in een database je niet heel veel op: in feite mitigeert dat alleen het risico 'iemand kan wel bij de database maar niet bij de sleutel die in je php-code gewoon beschikbaar is'. Het zorgt er niet voor dat de verkeerde mensen niet bij de verkeerde berichten kunnen (immers: jouw php-code ontsleutelt die gewoon voor ze).

Of zijn je clients in dit geval in php geschreven en wil je tussen twee clients een beveiligd kanaal opzetten? Dan blijft de vraag: moet dat een encrypted kanaal zijn? Of is het op te lossen door de clients beperkte rechten te geven op de database/message bus?

[ Voor 20% gewijzigd door ValHallASW op 27-06-2025 12:36 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 17:52

Janoz

Moderator Devschuur®

!litemod

Wat ValHalASW ook al aangeeft, volgens mij is er hier iets fundamentel mis met de aanpak. Als je echt E2E encryptie hebt hoef je in je backend helemaal niks met encryptie libraries. Jij krijgt onleesbare gegevens binnen en slaat die op, danwel stuurt ze door. Het zijn alleen de clients die daar chocola van kunnen maken.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'

Pagina: 1