Med alla de senaste uppgifterna har privatlivet blivit ett viktigt ämne. Nästan varje app kommunicerar via nätverket, så det är viktigt att överväga säkerheten för användarinformation. I det här inlägget läser du nuvarande bästa praxis för att säkra kommunikationen för din Android-app.
När du utvecklar din app är det bästa sättet att begränsa dina nätverksförfrågningar till de som är nödvändiga. För de väsentliga, se till att de är gjorda över HTTPS istället för HTTP. HTTPS är ett protokoll som krypterar trafik så att det inte enkelt kan avlyssas av eavesdroppers. Det bra med Android är att migrering är lika enkelt som att ändra webbadressen från http till https.
URL-URL = Ny webbadress ("https://example.com"); HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection (); httpsURLConnection.connect ();
Faktum är att Android N och högre versioner kan hantera HTTPS med hjälp av Androids Nätverkssäkerhetskonfiguration.
I Android Studio väljer du app / res / xml katalog för ditt projekt. Skapa xml katalog om den inte existerar redan. Markera den och klicka Fil> Ny fil. Kalla det network_security_config.xml. Formatet för filen är som följer:
example.com
För att berätta för Android att använda den här filen, lägg till namnet på filen till programtaggen i filen AndroidManifest.xml fil:
Uppdatera krypteringsleverantörer
HTTPS-protokollet har utnyttjats flera gånger under åren. När säkerhetsforskare rapporterar sårbarheter är defekterna ofta patchade. Applikationerna gör att dina appens nätverksanslutningar använder de mest uppdaterade branschstandardprotokollen. De senaste versionerna av protokollen innehåller färre svagheter än de föregående.
För att uppdatera krypteringsleverantörerna måste du inkludera Google Play Services. I din modulfil av build.gradle lägger du till följande rad i avsnitten:
implementering "com.google.android.gms: play-services-safetynet: 15.0.1"SafetyNet-tjänster API har många fler funktioner, inklusive Safe Browsing API som kontrollerar webbadresser för att se om de har markerats som ett känt hot och ett reCAPTCHA API för att skydda din app mot spammare och annan skadlig trafik.
När du har synkroniserat Gradle kan du ringa
ProviderInstaller
'sinstallIfNeededAsync
metod:public class MainActivity utökar Aktivitetsverktygen ProviderInstaller.ProviderInstallListener @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); ProviderInstaller.installIfNeededAsync (detta, detta);De
onProviderInstalled ()
Metoden heter när leverantören har uppdaterats, eller redan uppdaterad. Annat,onProviderInstallFailed (int errorCode, Intent recoveryIntent)
kallas.Certifikat och Public Key Pinning
När du gör en HTTPS-anslutning till en server presenteras ett digitalt certifikat av servern och valideras av Android för att säkerställa att anslutningen är säker. Certifikatet kan undertecknas med ett certifikat från en mellanliggande certifikatmyndighet. Detta certifikat som används av den mellanliggande myndigheten kan i sin tur undertecknas av en annan mellanliggande myndighet och så vidare, vilket är trovärdigt så länge som det sista certifikatet är signerat av en rootcertifikatmyndighet som redan är betrodd av Android OS.
Om något av certifikaten i förtroendekedjan inte är giltigt är anslutningen inte säker. Även om detta är ett bra system är det inte idiotiskt. Det är möjligt för en angripare att instruera Android OS att acceptera anpassade certifikat. Avlyssningsfullmäktige kan ha ett certifikat som är betrodd, och om enheten styrs av ett företag, kan företaget ha konfigurerat enheten att acceptera sitt eget certifikat. Dessa scenarier möjliggör en "man i mitten" -attack, så att HTTPS-trafiken kan dekrypteras och läsas.
Certifikatbeläggning kommer till räddning genom att kontrollera serverns certifikat som presenteras mot en kopia av det förväntade certifikatet. Detta förhindrar att anslutningar görs när certifikatet skiljer sig från det förväntade.
För att implementera pinning på Android N och högre måste du lägga till en hash (kallad stift) i certifikatet i network_security_config.xml fil. Här är ett exempel implementering:
duckduckgo.com lFL47 + i9MZkLqDTjnbPTx2GZbGmRfvF3GkEh + J + 1F3g = w9MWhhnFZDSPWTFBjaoeGuClsrCs7Z70lG7YNlo8t + s = För att hitta stiften för en viss webbplats kan du gå till SSL Labs, ange sajten och klicka Lämna. Eller om du utvecklar en app för ett företag kan du fråga företaget för det.
Obs! Om du behöver stödja enheter som kör en OS-version som är äldre än Android N kan du använda TrustKit-biblioteket. Det använder nätverkssäkerhetskonfigurationsfilen på exakt samma sätt.
Sanitisering och validering
Med alla skydd så långt måste dina anslutningar vara ganska säkra. Ändå, glöm inte regelbunden programmeringsvalidering. Blindtroende data som tas emot från nätverket är inte säkert. En bra programmeringspraxis är "design by contract", där ingångarna och utgångarna i dina metoder uppfyller ett kontrakt som definierar specifika gränssnittsförväntningar.
Om din server förväntar sig en sträng på 48 tecken eller mindre, se till att gränssnittet bara returnerar upp till och med 48 tecken.
om (editText.getText (). toString (). längd () <= 48) ; //return something… else ; //return default or errorOm du bara förväntar dig siffror från servern bör dina inmatningar kontrollera detta. Även om detta hjälper till att förhindra oskyldiga fel, minskar också sannolikheten för injektion och minneskorruption. Detta gäller särskilt när data överförs till NDK eller JNI-infödd C och C ++-kod.
Detsamma gäller för att skicka data till servern. Skicka inte blinda data ut, särskilt om den är användargenererad. Det är till exempel bra att begränsa längden på användarinmatning, speciellt om den kommer att köras av en SQL-server eller någon teknik som kör kod.
Samtidigt som du säkrar en server mot attacker ligger utanför ramen för den här artikeln, som mobilutvecklare kan du göra din del genom att ta bort tecken för det språk som servern använder. På så sätt är ingången inte mottaglig för injektionsattacker. Några exempel är strippande citat, semikolon och snedstreck när de inte är viktiga för användarens inmatning:
string = string.replace ("\\", "") .replace (";", "") .place ("\" "," ") .place (" \ "", "");Om du vet exakt det format som förväntas bör du kontrollera detta. Ett bra exempel är e-validering:
privat sista sträng emailRegexString = "^ [A-Za-z0-9 ._% + \\ -] + @ [A-Za-z0-9. \\ -] + \\. [A-Za-z] 2,4 $ "; privat booleansk isValidEmailString (String emailString) return emailString! = null && Pattern.compile (emailRegexString) .matcher (emailString) .matches ();Filer kan också kontrolleras. Om du skickar ett foto till din server kan du kontrollera att det är ett giltigt foto. De första två byte och sista två byte är alltid
FF D8
ochFF D9
för JPEG-format.privat statisk boolean isValidJPEGAtPath (String pathString) slår IOException RandomAccessFile randomAccessFile = null; försök randomAccessFile = ny RandomAccessFile (pathString, "r"); lång längd = randomAccessFile.length (); om (längd < 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();Var försiktig när du visar en felmeddelande som direkt visar ett meddelande från servern. Felmeddelanden kan avslöja privat debugging eller säkerhetsrelaterad information. Lösningen är att servern ska skicka en felkod som klienten ser upp för att visa ett fördefinierat meddelande.
Kommunikation med andra appar
Medan du skyddar kommunikation till och från enheten är det viktigt att skydda IPC också. Det har förekommit fall där utvecklare har lämnat delade filer eller genomfört uttag för att utbyta känslig information. Detta är inte säkert. Det är bättre att använda Avsikts. Du kan skicka data med hjälp av en Avsikt genom att tillhandahålla paketets namn så här:
Intent Intent = Ny Intent (); intent.setComponent (nytt komponentnamn ("com.example.app", "com.example.app.TheActivity")); intention.putExtra ("UserInfo", "Exempelsträng"); startActivity (intent);Om du vill sända data till fler än en app ska du se till att endast appar som skrivs med din signeringsnyckel får data. Annars kan den information du skickar läsas av alla appar som registrerar dig för att ta emot sändningen. På samma sätt kan en skadlig app skicka en sändning till din app om du har registrerat dig för att ta emot sändningen. Du kan använda ett tillstånd när du skickar och tar emot sändningar var signatur används som protectionLevel. Du kan definiera ett anpassat tillstånd i manifestfilen så här:
Då kan du bevilja tillståndet enligt följande:
Båda programmen måste ha behörigheterna i manifestfilen för att den ska fungera. För att skicka sändningen:
Intent Intent = Ny Intent (); intention.putExtra ("UserInfo", "Exempelsträng"); intent.setAction ( "com.example.SOME_NOTIFICATION"); sendBroadcast (avsikt, "com.example.mypermission");Alternativt kan du använda
setPackage (String)
när du skickar en sändning för att begränsa den till en uppsättning appar som matchar det angivna paketet. Miljöandroid: exporteras
tillfalsk
I manifestfilen kommer exkludera sändningar som tas emot från din app.End-to-End-kryptering
Det är viktigt att förstå gränserna för HTTPS för att skydda nätverkskommunikation. I de flesta HTTPS-implementeringar avslutas krypteringen på servern. Till exempel kan din anslutning till en företags server vara över HTTPS, men när den trafiken träffar servern är den okrypterad. Den kan sedan vidarebefordras till andra servrar, antingen genom att upprätta en annan HTTPS-session eller genom att skicka den okrypterad. Bolaget kan se informationen som har skickats, och i de flesta fall är det ett krav på affärsverksamhet. Det innebär emellertid också att företaget kan skicka informationen till tredje part okrypterad.
Det finns en ny trend som kallas "end-to-end-kryptering", där endast de tvåa kommunikationsenheterna kan läsa trafiken. Ett bra exempel är en krypterad chattapp där två mobila enheter kommunicerar med varandra via en server; endast avsändaren och mottagaren kan läsa varandras meddelanden.
En analogi som hjälper dig att förstå end-to-end-kryptering är att föreställa dig att du vill att någon ska skicka ett meddelande som du bara kan läsa. För att göra detta ger du dem en låda med ett öppet hänglås på den (den offentliga nyckeln) medan du håller hänglåsnyckeln (privat nyckel). Användaren skriver ett meddelande, lägger det i lådan, låser hänglåset och skickar det tillbaka till dig. Endast du kan läsa meddelandet eftersom du är den enda med nyckeln för att låsa upp hänglåset.
Med end-to-end kryptering skickar båda användarna sina nycklar. Servern tillhandahåller bara en tjänst för kommunikation, men den kan inte läsa innehållet i kommunikationen. Medan implementeringsinformationen ligger utanför ramen för denna artikel är den en kraftfull teknik. Om du vill lära dig mer om detta tillvägagångssätt är ett bra ställe att starta GitHub repo för det öppna Signal-projektet.
Slutsats
Med alla nya privatlivslagar som GDPR är säkerheten allt viktigare. Det är ofta en försummad aspekt av mobilapputveckling.
I den här handledningen har du deklarerat bästa praxis för säkerhet, inklusive användning av HTTPS, certifikatbeläggning, datasanering och end-to-end-kryptering. Dessa bästa metoder bör fungera som grund för säkerhet när du utvecklar din mobilapp. Om du har några frågor, var god att lämna dem nedan, och medan du är här, kolla in några av mina andra handledning om Android App Security!