[JAVA] Gebruikersgegevens veilig lokaal opslaan

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 18-09 17:57
Al geruime tijd werk ik aan een relatief simpele applicatie in JAVA, bestaande uit twee delen: client & server. De server heeft toegang tot bepaalde databases & SOAP services, de client heeft een GUI die gebruikers in staat stelt om hier dingen simpel op aan te vragen of bewerken. So far so good.

Nu is dit in feite een management applicatie voor een erg grote andere applicatie, die onder andere allang een user login systeem heeft. Wederom, geen probleem, de client verstuurt bij het inloggen een hash van username & wachtwoord door naar de server (via een simpele socket verbinding, een MitM attack verwacht ik eigenlijk niet, zo spannend is het allemaal niet), die vervolgens de gegevens vergelijkt met de gegevens in de database (waar enkel de hash opgeslagen is) en al dan niet de user accepteert.

Zoals gezegd, extreem spannend is het allemaal niet. Vandaar ook dat ik het liefst gebruikers de mogelijkheid geef om automatisch in te loggen. Dit betekend dus dat de gebruikersnaam en password hash ergens opgeslagen moeten worden, en daar zit'm het probleem: wat is de beste manier om dit veilig (cross platform) te doen?

Deze post geeft een aantal generieke methodes om gebruikersgegevens op te slaan, maar ik ben er toch een beetje huiverig voor om logingegevens simpelweg als plain-text ergens neer te plempen. Nu lijkt er wel iets te zijn als een keystore, maar ik krijg de indruk dat die meer bedoeld is voor security certificates, niet userdata.

Wat ik zoek:
- lokaal, cross-platform gegevens opslaan.
- gegevens alleen uitleesbaar op die pc, liefst alleen door die user.
- liefst standaard API, dat ik geen dikke libraries mee moet sturen enkel voor een wachtwoord opslaan vinkje.

Kan me haast niet voorstellen dat dit niet erg triviaal is voor ervaren JAVA coders, maar Google wil me alleen een dozijn verschillende manieren aanbieden om userdata serverside op te slaan - en dat zoek ik dus juist niet :+

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 08:51

Janoz

Moderator Devschuur®

!litemod

Kijk eens naar java preferences. Standaard in de JRE. Deze slaat de gegevens op een OS afhankelijke manier op. Deze heeft twee 'rootnodes': System en user. User is in principe enkel toegankelijk voor de gebruiker. Voor Windows wordt het registry gebruikt, op linux wordt er een .Java/preferences (waarbij de laatste 700 heeft) en voor OSX schijnt het ook wel op een nette plek terecht te komen.

Helemaal prive is het eigenlijk niet. Elke applicatie die hetzelfde package gebruiken en door dezelfde gebruiker gestart wordt kan bij de gegevens. Eigenlijk kan elke applicatie die door de gebruiker wordt gestart wel bij de gegevens. Ook een administrator kan natuurlijk regedit open gooien en kijken wat er opgeslagen is.

Ikzelf heb wel wachtwoorden op (moeten) slaan, maar ik heb er voor gezorgd dat ze iig niet zomaar te lezen zijn (helaas kan ik geen hash gebruiken in mijn situatie omdat ik het originele wachtwoord weer nodig heb). In jou situatie zou ik dan ook een soort token oplossing toepassen. De eerste keer dat de gebruiker inlogt met zijn gegevens en aangeeft ingelogd te blijven geeft de server een token terug die vervolgens door de client en de server onthouden wordt. Het voordeel is dat, wanneer de token gestolen wordt er gewoon een nieuwe uitgegeven kan worden. Het wachtwoord van de gebruiker ligt dan nog steeds niet op straat en de gebruiker hoeft ook geen nieuw wachtwoord te verzinnen omdat de hash gejat is.

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


Acties:
  • 0 Henk 'm!

  • OrbitZ
  • Registratie: Juni 2001
  • Laatst online: 26-05 13:07
Op Windows heb je de mogelijkheid om met CryptProtectData gegevens veilig op te slaan.

Echter is het, buiten de bovengenoemde Windows methode, niet mogelijk om de gegevens cross platform veilig op te slaan zonder een soort master password te gebruiken.

De CryptProtectData code voor Java is te vinden in Eclipse, deze maakt gebruik van deze integratie methode via JNI integratie.

Als je er verder van uit gaat dat je code niet gedecompileerd wordt dan zou je ook gebruik kunnen maken van een simpelere manier van encryptie, dit is dan niet 100% waterdicht maar beter dan plain text :)

Voor simpele encryptie kan je bijvoorbeeld even hier of hier naar kijken.

[ Voor 93% gewijzigd door OrbitZ op 01-04-2010 08:01 ]


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 18-09 17:57
@OrbitZ: bedankt voor de links! CryptProtectData ziet er inderdaad uit als precies datgene wat ik zoek - jammer dat het windows-only is, als zoiets nou cross-platform zou werken was ik snel klaar geweest :) De sourcecode van mijn applicatie is overigens vrij beschikbaar dus een simpele encryptie zal denk ik niet veel helpen.

Kans is trouwens vrij groot dat 95% toch de client onder windows draait, eventueel missen de mac & linux users dan maar een feature - ook geen enorm probleem.

@Janoz: erg interessant idee - feitelijk implementeer ik dan dus een session cookie, waarbij alle gevoelige informatie mooi op de server blijft en de client enkel de cookie houdt. Blijf ik wel met het probleem zitten dat het equivalent van session-theft in principe nog steeds mogelijk is - al wordt het wel simpeler om bijvoorbeeld user IP & system username in de hash op te nemen en een nieuw token uit te geven bij elke login (plus alle tokens direct invalidaten zodra een conflict voorkomt). Wat complexer dan ik had gehoopt, maar het is in elk geval een goede optie :)

[ Voor 8% gewijzigd door FragFrog op 01-04-2010 11:33 ]

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • OrbitZ
  • Registratie: Juni 2001
  • Laatst online: 26-05 13:07
@FragFrog

Mocht je geïnteresseerd zijn kan ik je wel even een zipje sturen met de Java/C++ sources van de Eclipse plugin.

Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
FragFrog schreef op donderdag 01 april 2010 @ 11:31:
@Janoz: erg interessant idee - feitelijk implementeer ik dan dus een session cookie, waarbij alle gevoelige informatie mooi op de server blijft en de client enkel de cookie houdt. Blijf ik wel met het probleem zitten dat het equivalent van session-theft in principe nog steeds mogelijk is - al wordt het wel simpeler om bijvoorbeeld user IP & system username in de hash op te nemen en een nieuw token uit te geven bij elke login (plus alle tokens direct invalidaten zodra een conflict voorkomt). Wat complexer dan ik had gehoopt, maar het is in elk geval een goede optie :)
Met je huidige manier van inloggen is session theft denk ik van mindere zorg. Als ik niet aan je session kan komen, dan kan ik vast wel een inlogsessie sniffen en replayen.

Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 18-09 17:57
Dan moet je wel op de juiste poort een monitoringsprogramma draaien wat al het verkeer bijhoudt wat er overheen gaat Remus, dat is toch net even een stuk lastiger dan een text bestandje kopieeren.

Het gaat me er vooral om dat als iemand z'n client doorstuurt naar iemand anders (bijvoorbeeld door even een zipje naar een collega te sturen, of simpelweg de client in een publieke share laten staan) deze niet ook automatisch kan inloggen met dezelfde credentials. Zodra iemand een packetsniffer kan installeren kan hij ook wel een keylogger installeren, daar valt toch helaas weinig aan te doen (zonder externe token generator in elk geval). Je hebt natuurlijk gelijk dat een beveiliging zo sterk is als de zwakste schakel, maar ik concentreer me liever nu op een veilige manier om inloggegevens op te slaan zodat ik eventueel later altijd nog de verbinding zelf kan encrypten.

OrbitZ: bedankt voor het aanbod, maar ik ontwikkel de client helaas in Netbeans - ik weet niet of een eclipse plugin dan nuttig is? Sowieso ben ik wat verder gaan lezen en tot de conclusie gekomen dat het niet veel meer of minder werk is om Janoz' idee te implementeren en aangezien dat wel cross-platform werkt ben ik momenteel meer geneigd daar maar voor te kiezen :)

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
FragFrog schreef op vrijdag 02 april 2010 @ 00:18:
Dan moet je wel op de juiste poort een monitoringsprogramma draaien wat al het verkeer bijhoudt wat er overheen gaat Remus, dat is toch net even een stuk lastiger dan een text bestandje kopieeren.
De exacte poort hoef ik niet te weten, een network analyzer zoals wireshark in promiscuous mode in een niet goed ingericht netwerk kan al voldoende zijn.
Het gaat me er vooral om dat als iemand z'n client doorstuurt naar iemand anders (bijvoorbeeld door even een zipje naar een collega te sturen, of simpelweg de client in een publieke share laten staan) deze niet ook automatisch kan inloggen met dezelfde credentials. Zodra iemand een packetsniffer kan installeren kan hij ook wel een keylogger installeren, daar valt toch helaas weinig aan te doen (zonder externe token generator in elk geval). Je hebt natuurlijk gelijk dat een beveiliging zo sterk is als de zwakste schakel, maar ik concentreer me liever nu op een veilige manier om inloggegevens op te slaan zodat ik eventueel later altijd nog de verbinding zelf kan encrypten.
Gebruik van een nonce zou al goed werken. Bijvoorbeeld: server stuurt nonce naar client, client stuurt naar server: {username, hash van({nonce, username, passwordhash})}; de server voert dezelfde hash uit en vergelijkt het resultaat. Niet 100% secure, maar vergt verder geen encryptie en beschermt tegen een replayattack.

Zie ook http://en.wikipedia.org/wiki/Cryptographic_nonce (waar een voorbeeld staat waarbij de client ook een nonce genereert).

BTW: Gezien je oorspronkelijke vraag, is dit misschien een interessant artikel
http://www.drdobbs.com/windows/184416587

[ Voor 5% gewijzigd door Remus op 02-04-2010 12:49 . Reden: English brain-fart ]


Acties:
  • 0 Henk 'm!

Verwijderd

JavaDB (ie Apache Derby) ondersteund encryptie en leent zich opzich wel voor clientside caching.

Wellicht kan je kijken of je met JNI kan integreren met de verschillende platformen; Gnome Keymanager, Windows Keyring, etc (Zal wel redelijk wat werk zijn).
Pagina: 1