Gå til innhold

Anbefalte innlegg

SItter med et programmeringsprosjekt med klient-server kommunikasjon. Jeg skriver for anledningen i java, men spørsmålet er ganske generelt.

 

Saken er at server skal lagre en brukers data kryptert. Eneste måten å dekryptere dataene på skal være ved bruk av brukerens passord. Data skal ikke dekrypters på server, noen gang. Klienten kan være en pc-app, mobil-app, eller annet. Det er ikke ønskelig at bruker skal trenge å overføre krypteringsnøkler mellom sine enheter hvor klienten er installert.

 

Her er det fare for at jeg er i ferd med å finne opp hjulet på nytt, men jeg har ikke funnet noen ferdigtenkte metoder som har passet til at brukers private key ligger på server.

 

Så da tenker jeg følgende innloggingsprosedyre:

- server har brukers public og privat passordkryptert key
- klient kobler til, får servers public key
- bruker skriver brukernavn
- klient krypterer brukernavn med servers public key, og sender til server
- server dekrypterer, finner brukers public og private key, sender en random streng kryptert med brukers public key og brukers private key
- bruker skriver passord
- klient låser opp private key med passordet og dekrypterer serverens random streng med brukers private key
- klient svarer server med å sende servers random streng tilbake kryptert med servers public key
- server godtar innlogging om mottatt streng passer med sendt streng

 

problemet der er at uvedkommende kan få tak i brukers passordkrypterte private key ved å installere klienten på sin egen pc/mobil og sende en brukers brukernavn. Med den krypterte private keyen sendt til klient, har en angriper uendelig med forsøk på seg for å forsøke å dekryptere nøkkelen. Hvordan kan man modifisere dette systemet for å ungå den risikoen?

 

Hvilke andre angrepsformer er denne metoden sårbar for?

Lenke til kommentar
Videoannonse
Annonse

Det er ikke ønskelig at bruker skal trenge å overføre

krypteringsnøkler mellom sine enheter hvor klienten er

installert.

 

Neivel. Men hvorfor er det ønskelig å gjøre asymmetrisk krypto? Hvorfor kan

man ikke basere dekryptering på på et passord som brukeren har (som brukeren

vil uansett måtte taste inn i en eller annen form).

 

Her er det fare for at jeg er i ferd med å finne opp hjulet på

nytt, men jeg har ikke funnet noen ferdigtenkte metoder som har

passet til at brukers private key ligger på server.

 

Jeg sliter med å forstå hovedsaklig hvorfor du velger asymmetrisk

kryptografi. Hvorfor er det gunstigere i dette scenarioet å ha et

public-private nøkkelpar? Dvs. hvilket problem er det et nøkkel*par* løser

her, som ikke kunne løses av:

 

1) En "STORE"-kommando, som sender en kryptert blob og lagrer det under en

gitt UUID.

2) En "RETRIEVE"-kommando, som henter en gitt kryptert blob for en gitt UUID.

 

Både krypteringsalgoritmen og passordet for å dekryptere data trenger ikke å

være kjent for serveren. En såpass triviell løsning vil ikke engang kreve

registrering. Om man ønsker registrering og/eller støtte for DELETE, kan man

alltids utvide protokollen med et registreringssteg[*] (over TLS, opplagt), og

sørge for at alle kommandoene sendes med et brukernavn (igjen, over TLS).

 

[*] registrering skjer en gang, brukeren velger brukernavn og passord (TLS +

captcha, omtrent som alle nettsider i dag), serveren husker passordhashen og

brukernavnet. Nå har TLS et nøkkelpar i bunn, men systemet slik det er i dag

inneholder i tillegg rutiner for tillitt, sertifikatinndragelse og alt mulig

annet, som du ikke slipper unna om du skal lage din egen versjon av TLS.

 

Hva er det asymmetrisk krypto for _kryptering av brukernes data_ vil gi deg

her?

 

Så da tenker jeg følgende innloggingsprosedyre:

 

Du nevner absolutt ingenting om hvordan du har tenkt å sørge for at klienten

validerer at oppkoblingen faktisk er mot den rette tjeneren. Har du tenkt å

kjøre din egen protokoll over TLS? Hvis ja, kjøper du da et skikkelig

sertifikat? Hvis ja, hvordan har du tenkt å migrere til en annen server?

 

- server har brukers public og privat passordkryptert key

- klient kobler til, får servers public key

- bruker skriver brukernavn

- klient krypterer brukernavn med servers public key, og sender til server

- server dekrypterer, finner brukers public og private key, sender en random

streng kryptert med brukers public key og brukers private key

 

Det at du skriver "klient krypterer brukernavn", får meg til å tro at du ikke

har tenkt å bruke TLS overhodet her. I så fall er systemet ubrukelig (hvordan

vet brukeren at det nøkkelparet brukeren har fått egentlig stammer fra

tjeneren?); men det kan godt hende jeg misforstod noe -- hvordan beskytter du

klienten mot MITM?

  • Liker 1
Lenke til kommentar

Takk for kritisk og godt svar. Akkurat slik som trengs for å tvinge en til å tenke igjennom en gang til.

 

Asymetrisk er valgt for at server og/eller andre brukere skal kunne legge inn data som bare mottagende bruker skal kunne lese. Ikke at det står øverst på spekklista, men det er noe jeg tror kan komme til nytte en etterhvert, så da er det kjekt å ha muligheten.

 

 

MIM tror jeg kan løses ved at klienten kjenner serverens public key på forhånd (lastet ned via sikker forbindelse ved installasjon). Når klienten sender brukernavn kryptert med serverens public key, og får brukerens private key, kryptert (symetrisk) med brukers passord, så vil jo klienten vite at dette kommer fra rett server dersom dekrypteringen av brukers private key lykkes.

Men det forutsetter jo at brukers krypterte private key ikke kan falle i hendene på uvedkomne, og det er jo akkurat der problemet med den skisserte metoden ligger.

 

Kan det løses med en runde hvor server og klient identifiserer hverandre først, før man begynner å blande inn brukeren? Hvordan bør i tilfelle det gå for seg?

 

 

Det stemmer at jeg ikke tenkte å bruke TLS. Rett og slett fordi alle data som sendes til serveren ikke skal dekrypteres av server, men lagres i sin krypterte form. Og motsatt - alt som hentes av klienten dekrypteres først når det har kommet frem til klienten. Dermed blir det litt smør på flesk å kryptere dette på nettverksnivå i tillegg. Objekter som sendes består av en kontrolldel og en datadel. Kontrolldelen skal (de)krypteres av server, mens datadelen skal rett i database/filsystem. Så i steden for å ha en ukryptert kontrolldel og en kryptert datadel, og kryptere hele objektet på nettverksnivå, tenker jeg altså å ha kontroll og data med hver sin kryptering i et ukryptert objekt.

 

Grunnen til dette er f.eks for å åpne for muligheten til at en mobil kan gjøre data tilgjengelig offline, hvor da dataene kan ligge kryptert på mobilen og først dekrypteres når de skal åpnes. Mobilen vil da ikke trenge å bruke batteri på dekryptering når dataene mottas fra server.

Lenke til kommentar

Asymetrisk er valgt for at server og/eller andre brukere skal

kunne legge inn data som bare mottagende bruker skal kunne

lese.

 

Men dette er et forhold som gjelder kun på klientsiden. Dvs. tjeneren burde gi

døyten i hva slags kryptoløsning klientene har valgt; for den er *all* data

bare blober.

 

Slik jeg tolket oppgaven er det 2 separate forhold som må sikres her:

 

1) kommunikasjon mellom klienten og tjeneren (med gjensidig autentisering)

2) krypteringen av dataene som skal lagres.

 

Dette er to helt adskilte forhold, og selv om #1 krever i praksis

TLS+brukernavn, gjør ikke #2 det.

 

Hvis "kryptert lagring" skal ha noe verdi, så kan ikke klienten stole på at

tjeneren oppbevarer data sikkert (noe en del dropbox-brukere ikke ser ut til å

ofre mange tanker). Selv om sikkerheten til løsningen ikke skal hvile på det,

er det faktisk ingen grunn til å fortelle tjeneren eksakt hva som er lagret og

på hvilket format, snarere tvert i mot.

 

Ikke at det står øverst på spekklista, men det er noe jeg tror kan komme til

nytte en etterhvert, så da er det kjekt å ha muligheten.

 

Løsningen for å kryptere data og protokollen mot tjeneren er to ortogonale

problemstillinger. Det burde sogar være mulig å bruke en rekke forskjellige

krypteringsmodi på klientsiden for data -- alt som kreves for å dekryptere er

at en klient kjenner algoritmen og de nødvendige initialparameterne.

 

Sagt enda mer forenklet -- hva er det din løsning tilbyr som denne løsningen

ikke vil tilby:

 

1) Skaffe et skikkelig sertifikat (gjøres årlig).

2) Registrere hver klient med brukernavn og passord på tjeneren over TLS. En

klient identifiseres av disse før en ytterligere kommando sendes. Gjøres

bare en gang for hver klient.

3) Tjeneren forstår GET/PUT/DELETE kommandoer. Alle over TLS.

4) Klienten bruker f.eks. TrueCrypt for å (de)kryptere dataene.

 

I sin simpleste form sender man en truecrypt container over TLS, hvilket er

smør på flesk. Man kan selvsagt gjøre en optimalisering, siden dataene er

kryptert, men det er egentlig ikke vesentlig.

 

MIM tror jeg kan løses ved at klienten kjenner serverens public key på forhånd

(lastet ned via sikker forbindelse ved installasjon).

 

Selv om du skulle ha en kanal for sikker nedlasting[1], er ikke dette alene

tilstrekkelig. Man må ha et opplegg for å trekke tilbake et sertifikat

(dvs. tjenerens public key) og man må ha en måte å verifisere at det

sertifikatet som tjeneren presenterer til klienten fremdeles er gyldig. Dette

betyr i praksis TLS med kjøpt sertifikat (thawte, verisign, hvem som

helst). Så kan man bruke openssl-biblioteket på klienten i sin helhet for å

sørge for at klienten autentiserer tjeneren.

 

[1] Jeg noterer også bak øret at "lastet ned via sikker forbindelse ved

installasjon" i praksis krever TLS+ditt sertifikat :) Så, siden du MÅ ha dette

i utgangspunktet, hvorfor rulle ut sin egen løsning?

 

Når klienten sender brukernavn kryptert med serverens public key, og får

brukerens private key, kryptert (symetrisk) med brukers passord, så vil jo

klienten vite at dette kommer fra rett server dersom dekrypteringen av brukers

private key lykkes.

 

Hvis TLS-forbindelsen er etablert (og man skrur på sertifikatvalidering) så

vil man ikke være sårbar for MITM. Men jeg forstår fremdeles ikke hvorfor

serveren skal administrere brukernes privatnøkler. "Lykkes" vil forresten

kreve bruk av signaturer, men det er vel løst gjennom kjennskap av tjenerens

sertifikat/public key.

 

Men det forutsetter jo at brukers krypterte private key

ikke kan falle i hendene på uvedkomne, og det er jo akkurat der problemet med

den skisserte metoden ligger.

 

Problemet er designfeil -- man skal ikke distribuere sine private

keys.

 

Kan det løses med en runde hvor server og klient identifiserer hverandre

først, før man begynner å blande inn brukeren? Hvordan bør i tilfelle det gå

for seg?

 

Dette løser ikke det underliggende problemet -- hva om tjeneren blir

kompromittert og alle klientenes nøkler er på avveie? De er krypterte (og det

er bra) men kan angripes nå offline.

 

Det stemmer at jeg ikke tenkte å bruke TLS.

 

Kort fortalt: you are fucked.

 

Litt lengre forklaring: du har ikke, reellt sett, et alternativ til et system

for håndtering av public keys. Ej heller er det lurt å lage sin egen protokoll

når det allerede finnes en skikkelig og velprøvd løsning.

 

Dermed blir

det litt smør på flesk å kryptere dette på nettverksnivå i tillegg.

 

Man trenger ikke det, egentlig. Det er bare mye enklere å si "man sender alt

over TLS og ikke bryr seg om evt. overhead". Man kan f.eks. sende sha1-summer

+ protokollinfo over TLS, og de faktiske krypterte dataene går over en annen

kanal slik de er (dvs. uten en ekstra kryptering).

 

Objekter som sendes består av en kontrolldel og en

datadel. Kontrolldelen skal (de)krypteres av server, mens datadelen skal rett

i database/filsystem. Så i steden for å ha en ukryptert kontrolldel og en

kryptert datadel, og kryptere hele objektet på nettverksnivå, tenker jeg altså

å ha kontroll og data med hver sin kryptering i et ukryptert objekt.

 

Mmm. Bare enklere å håndtere alt over samme forbindelse heller enn å styre med

en TLS-forbindelse og en klartekstforbindelse.

 

Grunnen til dette er f.eks for å åpne for muligheten til at en mobil

kan gjøre data tilgjengelig offline, hvor da dataene kan ligge kryptert på

mobilen og først dekrypteres når de skal åpnes. Mobilen vil da ikke trenge å

bruke batteri på dekryptering når dataene mottas fra server.

 

Har du regnet på hvor mange Wh du sparer på å sende en gjennomsnittlig fil

over TLS kontra klartekst? Fremdeles verdt det?

Lenke til kommentar

Server gir kan ikke gi døyten i hva slags kryptering som er valgt, da den kan få en forespørsel fra en klient om å sende over public key for en annen bruker, slik at en bruker kan legge inn kryptert beskjed til en annen bruker. Man kan ikke ta høyde for at hver bruker skal registrere sertifikat, så serveren må ta rollen som en slags lokal CA.

Løsningen må også kunne sikre at data ikke går tapt om en klientenhet forsvinner (stjeles, druknes, brennes...). Altså, hvis en brukers private key ikke ligger på server, blir man avhengig av at brukeren selv har tatt backup av denne. Dermed må private key legges på server og den må altså være kryptert.

Forslag til annen måte å løse dette på uten av private key må ligge på server? Man kunne selvsagt hatt en løsning med at bruker må kopiere sin nøkkel mellom alle klienter, men av erfaring fra et par nettbanker sier at dette oppfattes som en dårlig løsning av brukere.

 

Om så private key skal ligge på klienten, og denne klienten stjeles, er brått private key på avveie i en form hvor noen kan teste uendelig med passord for å dekryptere den. Det er altså ikke bare faren for kompromitering av serveren som setter dette i fare. Man kan i hvertfall bøte på noe av dette ved å ha en klientautentisering i tillegg til brukerautentiseringen. Hvordan skal man kunne få til det? Man må jo her ta høyde for at en bruker kan ha flere klienter, og kunne sperre en enkelt av dem. (Ved sperring kan man vel også ha en key-endring på alle brukerens data, slik at den privat keyen som er på avveie blir ubrukelig.)

hva er det din løsning tilbyr som denne løsningen ikke vil tilby:

1) Skaffe et skikkelig sertifikat (gjøres årlig).

2) Registrere hver klient med brukernavn og passord på tjeneren over TLS. En

klient identifiseres av disse før en ytterligere kommando sendes. Gjøres

bare en gang for hver klient.

3) Tjeneren forstår GET/PUT/DELETE kommandoer. Alle over TLS.

4) Klienten bruker f.eks. TrueCrypt for å (de)kryptere dataene.

1: cert for server finnes allerede. Riktignok i 3årig versjon.

2: Å bruke TLS i tillegg kan man jo godt gjøre. Eneste ulempen er evt batteribruk på mobiler for å gjøre dobbel kryptering. Og om TLS gjør noen nytte avhenger jo av hvilken løsning man havner på til slutt. Det er ikke selve krypteringen som bekymrer, men autentiseringen. Og autentisering er jo ikke noe som ligger i TLS.

3: Server skal ha endel flere kommandoer enn det, men det blir utenfor tema for denne tråden.

4: Jeg har fundert mye på hvordan man best kan ta i bruk truecrypt til dette, men har så langt ikke funnet det praktiske mulig.

Truecrypt bruker synkron kryptering. Behovet for asynkron er nevnt før. Man kunne evt hatt synkron på noe og asynkron på annet.... Og det man kommer tilbake til er behovet for denne autentiseringen, og beskyttelsen av private key.

Kanal for sikker nedlasting er f.eks. at installasjon av klienter må gjøres mens enheten er på samme lan som serveren.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...