Sikring av kommunikasjon på Android

Med alle de siste data bruddene har personvern blitt et viktig tema. Nesten alle app kommuniserer over nettverket, så det er viktig å vurdere sikkerheten til brukerinformasjon. I dette innlegget lærer du dagens beste praksis for å sikre kommunikasjonen til Android-appen din.

Bruk HTTPS

Når du utvikler appen din, er det best å begrense dine nettverksforespørsler til de som er avgjørende. For de avgjørende, sørg for at de er laget over HTTPS i stedet for HTTP. HTTPS er en protokoll som krypterer trafikk, slik at den ikke lett kan skilles av eavesdroppers. Det gode ved Android er at migrering er like enkelt som å endre nettadressen fra http til https

URL-URL = Ny URL ("https://example.com"); HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection (); httpsURLConnection.connect ();

Faktisk kan Android N og høyere versjoner håndheve HTTPS ved å bruke Android's Network Security Configuration.

I Android Studio velger du app / res / xml katalog for prosjektet ditt. Opprett xml katalog hvis den ikke allerede eksisterer. Velg den og klikk Fil> Ny fil. Kall det network_security_config.xml. Formatet for filen er som følger:

   example.com  

For å fortelle Android å bruke denne filen, legg til navnet på filen til applikasjonstegnet i AndroidManifest.xml fil:

Oppdater krypteringsleverandører

HTTPS-protokollen har blitt utnyttet flere ganger gjennom årene. Når sikkerhetsforskere rapporterer sårbarheter, blir feilene ofte patched. Applikasjonene gjør at appens nettverksforbindelser bruker de mest oppdaterte industristandardprotokollene. De nyeste versjonene av protokollene inneholder færre svakheter enn de forrige. 

For å oppdatere krypteringsleverandørene må du inkludere Google Play-tjenester. I modulfilen til build.gradle legger du til følgende linje i avhengighetsdelen:

implementering 'com.google.android.gms: play-services-safetynet: 15.0.1'

SafetyNet-tjenesteprogrammet har mange flere funksjoner, inkludert API for sikker nettlesing som kontrollerer nettadresser for å se om de er merket som en kjent trussel, og en reCAPTCHA API for å beskytte appen din mot spammere og annen ondsinnet trafikk.

Etter at du har synkronisert Gradle, kan du ringe ProviderInstaller's installIfNeededAsync metode:

offentlig klasse MainActivity utvider Aktivitet implementerer ProviderInstaller.ProviderInstallListener @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); ProviderInstaller.installIfNeededAsync (dette, dette); 

De onProviderInstalled () Metoden kalles når leverandøren har blitt oppdatert, eller allerede oppdatert. Ellers, onProviderInstallFailed (int errorCode, Intent recoveryIntent) er kalt. 

Sertifikat og offentlig nøklepinne

Når du lager en HTTPS-tilkobling til en server, presenteres et digitalt sertifikat av serveren og validert av Android for å sikre at tilkoblingen er sikker. Sertifikatet kan bli signert med et sertifikat fra en mellomliggende sertifikatmyndighet. Dette sertifikatet som brukes av den mellomliggende autoriteten, kan i sin tur bli signert av en annen mellomliggende autoritet og så videre, som er troverdig så lenge det siste sertifikatet er signert av en rotteattestmyndighet som allerede er klarert av Android OS.

Hvis noen av sertifikatene i tillitskæden ikke er gyldige, er forbindelsen ikke sikker. Selv om dette er et godt system, er det ikke idiotsikkert. Det er mulig for en angriper å instruere Android OS for å godta egendefinerte sertifikater. Avlytende proxy kan ha et sertifikat som er klarert, og hvis enheten styres av et selskap, kan selskapet ha konfigurert enheten til å godta sitt eget sertifikat. Disse scenariene tillater et "mann i midten" angrep, slik at HTTPS-trafikken blir dekryptert og leset. 

Sertifikatpinne blir reddet ved å sjekke serverens sertifikat som presenteres mot en kopi av det forventede sertifikatet. Dette forhindrer at tilkoblinger blir gjort når sertifikatet er forskjellig fra den forventede.

For å implementere pinning på Android N og høyere, må du legge til en hash (kalt pins) av sertifikatet i network_security_config.xml fil. Her er et eksempel implementering:

   duckduckgo.com  lFL47 + i9MZkLqDTjnbPTx2GZbGmRfvF3GkEh + J + = 1F3g w9MWhhnFZDSPWTFBjaoeGuClsrCs7Z70lG7YNlo8t + s =   

For å finne pinnene for et bestemt nettsted, kan du gå til SSL Labs, skrive inn nettstedet, og klikk Sende inn. Eller hvis du utvikler en app for et selskap, kan du spørre selskapet for det.

Merk: Hvis du trenger å støtte enheter som kjører en OS-versjon som er eldre enn Android N, kan du bruke TrustKit-biblioteket. Den bruker nettverkssikkerhetskonfigurasjonsfilen på nøyaktig samme måte.

Sanitisering og validering

Med alle beskyttelsene så langt, må forbindelsene dine være ganske sikre. Likevel, ikke glem å regelmessig programmeringsvalidering. Blind tillit til data mottatt fra nettverket er ikke trygt. En god programmeringspraksis er "design by contract", hvor inngangene og utgangene til metodene dine tilfredsstiller en kontrakt som definerer spesifikke grensesnittforventninger. 

Hvis din server for eksempel forventer en streng på 48 tegn eller mindre, må du sørge for at grensesnittet bare returnerer til og med 48 tegn.

hvis (editText.getText (). toString (). lengde () <= 48)  ; //return something…  else  ; //return default or error 

Hvis du bare forventer tall fra serveren, bør dine innspillinger se etter dette. Selv om dette bidrar til å forebygge uskyldige feil, reduseres det også sannsynligheten for injeksjon og minnekorrupsjonsangrep. Dette gjelder spesielt når dataene overføres til NDK eller JNI-innfødt C og C ++-kode.

Det samme gjelder for å sende data til serveren. Ikke blindt sende data, spesielt hvis det er brukergenerert. For eksempel er det god praksis å begrense lengden på brukerinngang, spesielt hvis den blir utført av en SQL-server eller hvilken som helst teknologi som vil kjøre kode. 

Mens sikring av en server mot angrep er utenfor rammen av denne artikkelen, kan du som mobilutvikler gjøre din del ved å fjerne tegn for språket som serveren bruker. På den måten er inngangen ikke utsatt for injeksjonsangrep. Noen eksempler er stripping sitater, semikoloner og skråstreker når de ikke er avgjørende for brukerens innspill:

string = string.replace ("\\", "") .replace (";", "") .replace ("\" "," ") .replace (" \ '";" ");

Hvis du vet nøyaktig formatet som forventes, bør du sjekke dette. Et godt eksempel er e-post validering:

privat sluttstreng emailRegexString = "^ [A-Za-z0-9 ._% + \\ -] + @ [A-Za-z0-9. \\ -] + \\. [A-Za-z]  2,4 $ "; privat boolsk isValidEmailString (String emailString) return emailString! = null && Pattern.compile (emailRegexString) .matcher (emailString) .matches (); 

Filer kan også kontrolleres. Hvis du sender et bilde til serveren din, kan du sjekke at det er et gyldig bilde. De to første byte og siste to byte er alltid FF D8 og FF D9 for JPEG-format.

privat statisk boolsk isValidJPEGAtPath (String pathString) kaster IOException RandomAccessFile randomAccessFile = null; prøv randomAccessFile = ny RandomAccessFile (pathString, "r"); lang lengde = randomAccessFile.length (); hvis (lengde < 10L)  return false;  byte[] start = new byte[2]; randomAccessFile.readFully(start); randomAccessFile.seek(length - 2); byte[] end = new byte[2]; randomAccessFile.readFully(end); return start[0] == -1 && start[1] == -40 && end[0] == -1 && end[1] == -39;  finally  if (randomAccessFile != null)  randomAccessFile.close();   

Vær forsiktig når du viser et feilvarsel som direkte viser en melding fra serveren. Feilmeldinger kan avsløre privat feilsøking eller sikkerhetsrelatert informasjon. Løsningen er at serveren skal sende en feilkode som klienten ser opp for å vise en forhåndsdefinert melding.

Kommunikasjon med andre apper

Mens du beskytter kommunikasjon til og fra enheten, er det viktig å beskytte IPC også. Det har vært tilfeller hvor utviklere har forlatt delte filer eller har implementert stikkontakter for å utveksle sensitiv informasjon. Dette er ikke sikkert. Det er bedre å bruke Intents. Du kan sende data ved hjelp av en Intent ved å gi pakkenavn slik:

Intent Intent = Ny Intent (); intent.setComponent (nytt ComponentName ("com.example.app", "com.example.app.TheActivity")); intent.putExtra ("UserInfo", "Eksempel streng"); startActivity (hensikt);

For å kringkaste data til mer enn en app, bør du håndheve at bare apps som er signert med signeringsnøkkelen, vil få dataene. Ellers kan informasjonen du sender lese av en app som registrerer for å motta sendingen. På samme måte kan en skadelig app sende en kringkasting til appen din hvis du har registrert deg for å motta sendingen. Du kan bruke en tillatelse når du sender og mottar sendinger hvor signatur brukes som protectionLevel. Du kan definere en egendefinert tillatelse i manifestfilen slik:

 

Deretter kan du gi tillatelsen som dette: 

Begge programmene må ha tillatelsene i manifestfilen for at den skal fungere. For å sende kringkastingen:

Intent Intent = Ny Intent (); intent.putExtra ("UserInfo", "Eksempel streng"); intent.setAction ( "com.example.SOME_NOTIFICATION"); sendBroadcast (intent, "com.example.mypermission");

Alternativt kan du bruke setPackage (String) når du sender en kringkasting for å begrense den til et sett med apper som samsvarer med den angitte pakken. Innstilling android: eksportert til falsk I manifestfilen utelukkes sendinger som mottas fra utenfor appen din.

End-to-End-kryptering

Det er viktig å forstå grensene for HTTPS for å beskytte nettverkskommunikasjon. I de fleste HTTPS-implementeringer, avsluttes krypteringen på serveren. For eksempel kan forbindelsen til et selskaps server være over HTTPS, men når trafikken treffer serveren, er den ukryptert. Det kan da videresendes til andre servere, enten ved å etablere en annen HTTPS-økt eller ved å sende den ukryptert. Selskapet er i stand til å se informasjonen som er sendt, og i de fleste tilfeller er det et krav til forretningsvirksomhet. Imidlertid betyr det også at selskapet kunne overføre informasjonen til tredjeparter ukryptert.

Det er en ny trend som kalles "end-to-end-kryptering", der bare de to endelige kommunikasjonsenhetene kan lese trafikken. Et godt eksempel er en kryptert chat app hvor to mobile enheter kommuniserer med hverandre via en server; Bare avsenderen og mottakeren kan lese hverandres meldinger.

En analogi som hjelper deg med å forstå end-to-end-kryptering, er å forestille deg at du vil at noen skal sende deg en melding som bare du kan lese. For å gjøre dette, gir du dem en boks med en åpen hengelås på den (den offentlige nøkkelen) mens du holder hengelåseknappen (privat nøkkel). Brukeren skriver en melding, legger den i esken, låser hengelåsen og sender den tilbake til deg. Bare du kan lese meldingen fordi du er den eneste med nøkkelen til å låse opp hengelåsen.

Med end-to-end kryptering sender begge brukerne sine nøkler. Serveren gir bare en tjeneste for kommunikasjon, men den kan ikke lese innholdet i kommunikasjonen. Mens implementeringsdetaljer er utenfor rammen av denne artikkelen, er det en kraftig teknologi. Hvis du vil lære mer om denne tilnærmingen, er et flott sted å starte GitHub-repo for det åpen-sourced Signal-prosjektet.

Konklusjon

Med alle de nye personvernlovene som GDPR er sikkerheten stadig viktigere. Det er ofte et forsømt aspekt av mobilapputvikling.

I denne opplæringen har du dekket sikkerhetsbestemmelsene, inkludert bruk av HTTPS, sertifisering, sertifisering av data og end-to-end-kryptering. Disse beste rutene bør tjene som grunnlag for sikkerhet når du utvikler mobilappen din. Hvis du har noen spørsmål, vær så snill å la dem være under, og mens du er her, sjekk ut noen av mine andre veiledninger om Android App Security!