2FA toevoegen aan project

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Veur Heur

Veur Heur

09/03/2022 12:51:33
Quote Anchor link
Ik ben aan het kijken hoe ik 2FA kan toevoegen aan een bestaand systeem. Op dit moment loggen we in met naam en wachtwoord, hier is dus een extra laag gewenst. Nu ben ik bekend met hoe ik OTP-codes kan genereren op basis van een unieke key (of "secret"), het verzinnen van zo'n unieke key en het aanbieden als scanbare QR code om deze toe te voegen aan bijv. een Google Authenticator app zal ook nog wel lukken, echter vraag ik me af waar ik deze unieke key bewaar.

Is het veilig de code zomaar bij het user account te bewaren in de database of hoe pak ik dat aan?
 
PHP hulp

PHP hulp

28/03/2024 15:51:15
 
Ad Fundum

Ad Fundum

09/03/2022 15:05:44
Quote Anchor link
Je kan die sleutel (net als de hash van het wachtwoord) gewoon in de database opslaan, dat is wel zo gemakkelijk.
Al denk ik dat je jezelf heel goed moet afvragen of gebruik van Google diensten wel AVG-technisch wel door de beugel kan, over het algemeen is Google wat dat betreft puur gif. (Alleen al het aanbieden van lettertypen bij Google vandaan heeft een Duits bedrijf een boete opgeleverd).

Wat betreft de term sleutel, die vond ik in het begin lastig te begrijpen, omdat zowel de publieke sleutel als de private sleutel 'sleutel' worden genoemd. De werking bleek simpel, de publieke sleutel is publiek, en wordt gebruikt om mee te versleutelen. Maar alleen degene met de private sleutel kan de gegevens ontsleutelen.

Voor de rest is de werking dus hetzelfde als met het wachtwoord. Je slaat het wachtwoord niet op in de database, je slaat alleen de hash op. Als iemand een wachtwoord instuurt om te authenticeren, check je dat wachtwoord met de hash.
Nu met sleutels. Je slaat de publieke sleutel op in de database. Als iemand de private sleutel instuurt om te authenticeren, kan je beide sleutels gebruiken om iets te versleutelen en te ontsleutelen en zo valideren of de sleutels bij elkaar horen.
Na elke aanmeldpoging, gelukt of niet, wis je het wachtwoord en de private sleutel weer.

Net als met het genereren van wachtwoorden kan je ook een sleutelpaar laten genereren op het authenticatiesysteem, en dan bied je daarna de private sleutel aan als download. Je bewaart dan alleen de publieke sleutel.

Het is aan de gebruiker om zijn wachtwoorden / cryptografische sleutels te bewaren. Als je dat meteen goed wilt doen loont het om op zoek te gaan naar een goede wachtwoordmanager. Mocht je geen goede keuze kunnen maken dan is KeePass een goede optie. Met een add-on is de interface in het Nederlands te krijgen.
 
Veur Heur

Veur Heur

09/03/2022 15:12:55
Quote Anchor link
Dank voor je antwoord, het is me echter niet helemaal duidelijk. De secret wordt gebruikt om een OTP mee te maken, toch? Dit doe ik aan mijn kant (of althans in een app zoals Google Authenticator, kan ook een andere zijn), vervolgens zal ik server side de OTP moeten controleren. Als ik de hash opgeslagen heb, dan lukt dat toch niet? Het idee van een hash is toch dat die onomkeerbaar is?

OTP is toch niet iets van Google trouwens?
 
Ad Fundum

Ad Fundum

09/03/2022 15:48:47
Quote Anchor link
Sorry, mijn fout, ik had het per ongeluk over een iets andere manier van 2FA.

Een OTP op zichzelf is geen 2FA, maar een extra wachtwoord (dat maar van korte duur geldig is). Het idee is dat je dat wachtwoord gebruikt om iets anders te valideren, bijvoorbeeld iemands mobiele telefoonnummer, of een e-mailadres.

2FA (of gewoon multifactorauthenticatie) is dat een gebruiker zich authenticeert op 2 of meer manieren, waarbij onder manieren wordt verstaan:
1. iets wat iemand weet
2. iets wat iemand heeft
3. iets wat iemand is

Met andere woorden, als je gaat scannen met een QR code, moet je wel voor jezelf scherp hebben dat je niet een tweede keer authenticeert op basis van punt 1., want tweemaal een wachtwoord is geen 2FA. In het geval met de Google app zou ik niet weten op basis waarvan authenticatie verloopt, want Google mag niet zomaar binnen de EU worden ingezet voor iets dergelijks.

Dit alles gezegd hebbende, een tijdelijk gegenereerde sleutel (OTP) kan je best in een database opslaan. Als het heel tijdelijk is, zeg een paar minuten, is de kans op problemen niet heel groot. Maar dan moet je het wel onzettend veilig opslaan, zodat niemand anders daar bij kan. In complexe omgevingen zoals in de cloud kan het lastig zijn om dat goed te regelen.

Het blijft raadzaam om de OTP te genereren en uit te geven, en van de OTP alleen een hash op te slaan. Je zou hiervoor password_hash() en password_verify() kunnen gebruiken. Juist omdat OTP slechts een (tijdelijk) wachtwoord is, zou het niet moeilijk moeten zijn.
 
Veur Heur

Veur Heur

09/03/2022 15:59:03
Quote Anchor link
Oh, ik dacht dat OTP een onderdeel was van 2FA en bovenop user en pass een extra laag beveiliging. Klopt dit niet?

1. iets wat iemand weet > pass
2. iets wat iemand heeft > otp
3. iets wat iemand is > user

Het probleem zit hem in het feit dat ik niet weet hoe de OTP te genereren zonder de secret te kennen. Ik zou dan user, hashpass en secret op moeten slaan, maar is dat veilig?
Gewijzigd op 09/03/2022 15:59:35 door Veur Heur
 
Adoptive Solution

Adoptive Solution

09/03/2022 18:41:39
 
Veur Heur

Veur Heur

09/03/2022 20:08:20
Quote Anchor link
Zoals ik het dus zie, zal ik de secretkey dus toch gewoon bij het account op moeten slaan.
 
Ad Fundum

Ad Fundum

10/03/2022 09:39:02
Quote Anchor link
Ja dat klopt, OTP alleen is geen 2FA.
OTP is wat de naam al aangeeft, een wachtwoord dat eenmalig geldig is (One Time Password). En meestal heeft die ook maar een (zeer) beperkte geldigheidsduur, zoals een SMS-code die maar 2 minuten werkt.

En je ziet het goed, je moet inderdaad de 'secretkey' opslaan. Maar als je dat veilig wilt doen, is de eenvoudigste manier om een OTP-wachtwoord (de secretkey) te genereren, die aan de gebruiker te geven, en zelf alleen de hash op te slaan, net zoals je dat zou moeten doen met alle andere wachtwoorden. Hiervoor heeft PHP password_hash() en password_verify(). Als wachtwoord kan je gewoon een willekeurige reeks karakters genereren met random_bytes().

Je kunt een stap verder gaan met mijn eerste reactie. Het idee is hetzelfde maar in plaats van een OTP-wachtwoord gebruik je een cryptografisch sleutelpaar, waarbij je de public key opslaat en de private key aan de gebruiker geeft.

Als iemand probeert te authenticeren met zijn of haar accountnaam dan krijg je:
1. iets wat iemand weet --> het wachtwoord van de account
2. iets wat iemand heeft --> de private key, of elke keer een device controleren met een OTP
3. iets wat iemand is --> dit is meestal biometrie (vingerafdruk, gezichtsherkenning, DNA etc.)

Punt 3 is niet aan de orde, maar punt 2 is nu wel duidelijk. Het is van belang dat je bij punt 2 valideert wat iemand heeft, in de strikte zin, anders maakt een auditbureau gehakt van je authenticatie (dat is mijn ervaring).

Toevoeging op 10/03/2022 09:41:32:

Adoptive Solution op 09/03/2022 18:41:39:

Die verwijst naar Google Authenticator. Dat moet je niet willen als je iets ontwikkelt voor gebruik binnen de EU.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.