säkerhet med HTTPS och SSL

säkerhet med HTTPS och SSL

Secure Sockets Layer (SSL)—nu tekniskt känd som Transport Layer Security(TLS)—är acommon byggsten för krypterad kommunikation mellan klienter och servrar. Det är möjligt thatan applikation kan använda SSL felaktigt så att skadliga enheter kanske kan fånga upp en apps data över nätverket., För att hjälpa dig att se till att detta inte händertill din app, belyser den här artikeln de vanliga fallgroparna när du använder säkra nätverksprotokoll och tar upp några större problem med att använda Offentlig nyckelinfrastruktur (PKI).

Du bör också läsa AndroidSecurity översikt samt PermissionsOverview.

koncept

i ett typiskt SSL-användningsscenario konfigureras en server med ett certifikat som innehåller apublic-nyckel samt en matchande privat nyckel., Som en del av handslaget mellan en SSL-klientoch server visar servern att den har den privata nyckeln genom att underteckna sitt certifikat med kryptering med öppen nyckel.

men vem som helst kan generera sitt eget certifikat och privat nyckel, så en enkel handshakedoesn bevisa ingenting om servern annat än att servern vet den privata nyckeln som matchar den offentliga nyckeln i certifikatet. Ett sätt att lösa detta problem är att ha klientenhar en uppsättning av ett eller flera certifikat som den litar på. Om certifikatet inte finns i uppsättningen, servern är inte att lita på.,

det finns flera nackdelar med detta enkla tillvägagångssätt. Servrarna bör kunna gå till starkare nycklar över tiden (”nyckelrotation”), som ersätter den offentliga nyckeln icertifikatet med en ny. Tyvärr måste nu klientappen uppdateras på grund av vadär i huvudsak en serverkonfigurationsändring. Detta är särskilt problematiskt om servernär inte under apputvecklarens kontroll, till exempel om det är en tredje parts webbtjänst. Denna app har också problem om appen måste prata med godtyckliga servrar som en webbläsare oremail app.,

för att ta itu med dessa nackdelar konfigureras servrar vanligtvis med certifikatfrån välkända emittenter som kallas certifikatmyndigheter (CAs).Värdplattformen innehåller i allmänhet en lista över välkända CAs som det trusts.As av Android 4.2 (Jelly Bean) innehåller Android för närvarande över 100 CAs som uppdaterasi varje utgåva. I likhet med en server har en CA ett certifikat och en privat nyckel. När du utfärdar ett certifikat för en server signerar CASERVERCERTIFIKATET med sin privata nyckel. Theclient kan sedan verifiera att servern har ett certifikat utfärdat av en CA som är känd för plattformen.,

men samtidigt lösa vissa problem, med hjälp av CAs introducerar en annan. Eftersom CA utfärdarcertifikat för många servrar behöver du fortfarande något sätt att se till att du pratar med servern du vill ha. För att ta itu med detta identifierar certifikatet som utfärdats av den upphandlande myndigheten servereither med ett visst namn som gmail.com eller en wildcarded uppsättning hosts som *.google.com.

följande exempel kommer att göra dessa begrepp lite mer konkreta., I avsnittet nedanfrån en kommandorad ser kommandot openssls_client på Wikipedias servercertifikatinformation. Itspecifies port 443 eftersom det är standard för HTTPS. Kommandot skickar utdata från openssl s_client till openssl x509, vilket format informationom certifikat enligt X. 509-standarden. Specifikt frågar kommandot om ämnet, som innehåller servernamnsinformationen och emittenten, som identifierar CA.,

Du kan se att certifikatet utfärdades för servrar som matchar *.wikipedia.org av RapidSSL CA.

ett HTTPS-exempel

Om du antar att du har en webbserver med acertificate utfärdat av en välkänd CA, kan du göra en säker förfrågan med code assimple här:

Ja, det kan verkligen vara så enkelt. Om du vill skräddarsy HTTP-begäran kan du casta toan HttpURLConnection., Android-dokumentationen förHttpURLConnection har ytterligare exempel på hur man hanterar requestand response headers, posta innehåll, hantera cookies, använda fullmakter, cachningssvar och så vidare. Men när det gäller detaljerna för att verifiera certifikat och värdnamn tar Androidframework hand om det för dig genom dessa API: er.Det är här du vill vara om det alls är möjligt. Som sagt, nedan är några andra överväganden.,

den Gemensamma problem med att verifiera servercertifikat

Antag istället för att ta emot innehåll från getInputStream() det kastar ett undantag:

Detta kan hända av flera skäl, bland annat:

  1. CERTIFIKATUTFÄRDAREN som utfärdat servercertifikatet var okänd
  2. servercertifikatet inte var undertecknad av en CA, men var självsignerat
  3. serverns konfiguration saknas en mellanliggande certifikatutfärdare

följande avsnitt diskutera hur man ska hantera dessa problem och samtidigt hålla yourconnection att servern är säker.,

okänd certifikatutfärdare

i det här fallet uppstårSSLHandshakeException eftersom du har en CA som inte är betrodd av systemet. Det kan vara eftersomdu har ett certifikat från en ny CA som ännu inte är betrodd av Android eller din app isrunning på en äldre version utan CA. Ofta är en CA okänd eftersom det inte är en offentlig CA, men en privat som utfärdats av en organisation som en regering, företag eller utbildningsinstitution för eget bruk.

lyckligtvis kan du läraHttpsURLConnectionatt lita på en viss uppsättning CAs., Procedurenkan vara lite invecklad, så nedan är ett exempel som tar en specifik CA froman InputStream, använder den för att skapa en KeyStore,som sedan används för att skapa och initiera enTrustManager. ATrustManager är vad systemetanvänder för att validera certifikat från serverand—genom att skapa en från enKeyStore med en eller flera CAs—thosekommer att vara det enda CAs som är betrodda av detTrustManager.,

med tanke på den nyaTrustManagerinitierar exemplet ett nyttSSLContext som tillhandahållerSSLSocketFactory du kan använda för att åsidosätta standardSSLSocketFactory frånHttpsURLConnection. På så sätt kommer anslutningen att använda din CAs för certifikatvalidering.

här är exemplet ifull med hjälp av en organisatorisk CA från University of Washington:

med en anpassad TrustManager som vet om din CAs,systemet kan valideraatt ditt servercertifikat kommer från en betrodd emittent.,

Varning: många webbplatser beskriver en dålig alternativ lösning som är att installera enTrustManager som inte gör någonting. Om du gör detta kan du lika gärna inte att kryptera din kommunikation, eftersom vem som helst kan attackera dina användare på ett offentligt Wi-Fi hotspotby med hjälp av DNS-tricks för att skicka din användare’traffic genom en fullmakt av sina egna som utger sig för att vara servern. Angriparen kan dåregistrera lösenord och andra personuppgifter., Detta fungerar eftersom angriparen kan generera acertificate och—utan en TrustManager som actuallyvalidates att certifikatet kommer från en trustedsource-din app kan prata med vem som helst. Så gör inte det här, inte ens tillfälligt. Du kanalltid göra din app lita på emittenten av serverns certifikat, så gör det bara.

självsignerat servercertifikat

det andra fallet medSSLHandshakeException ärpå grund av ett självsignerat certifikat, vilket innebär att servern beter sig som sin egen CA.,Detta liknar en okänd certifikatutfärdare, så du kan användasamma tillvägagångssätt från föregående avsnitt.

Du kan skapa din egenTrustManager,den här gången lita på servercertifikatet direkt. Detta har alla thedownsides diskuteras tidigare för att binda din app direkt till ett certifikat, men kan donesecurely. Du bör dock vara noga med att se till att ditt självsignerade certifikat har en rimlig stark nyckel. Från och med 2012, en 2048-bitars RSA-signatur med en exponent av 65537 expiringyearly är acceptabelt., När du roterar nycklar bör du kontrollera rekommendationer från enmyndighet (till exempel NIST) om vad som är acceptabelt.

saknas Mellanliggande certifikatutfärdare

det tredje fallet med SSLHandshakeException uppstår på grund av en saknad mellanliggande CA. De flesta publicCAs signerar inte servercertifikat direkt. Istället använder de sitt huvudsakliga CA-certifikat,som kallas root CA, för att underteckna mellanliggande CAs. De gör detta så att root CA kan lagrasoffline för att minska risken för kompromiss., Dock operativsystem som Android typicallytrust bara rotcertifikatutfärdare direkt, vilket ger en kort förtroendeklyftan mellan servercertificate undertecknad av mellanliggande certifikatutfärdare och certifikat som kontrollör,som vet rotcertifikatutfärdare. Till solvethis skickar servern inte klienten bara sitt certifikat under SSL-handslaget, utan en certifikatkedja från serverns CA genom alla mellanprodukter som är nödvändiga för att nå atrusted root CA.

för att se hur det ser ut i praktiken, här är posten.google.,com certificatechain som visas av kommandotopenssls_client:

detta visar att servern skickar ett certifikat för e-post.google.comissued av Thawte SGC CA, som är en mellanliggande certifikatutfärdare, och en andra certificatefor Thawte SGC CA utfärdats av ett Verisign CA, som är den primära CA att’strusted av Android.

det är dock inte ovanligt att konfigurera en server för att inte inkludera den nödvändigaintermediate CA., Här är till exempel en server som kan orsaka ett fel i Android-webbläsare ochexceptioner i Android-appar:

det som är intressant att notera här är att besöka den här servern i de flesta skrivbordswebbläsareorsakar inte ett fel som ett helt okänt CA eller självsignerat servercertifikat skulleorsaka. Detta beror på att de flesta stationära webbläsare cache betrodda mellanliggande CAs över tiden. Oncea webbläsaren har besökt och lärt mig om en mellanliggande certifikatutfärdare från en webbplats, kommer det’tneed att ha den mellanliggande certifikatutfärdare ingår i certifikatkedjan nästa gång.,

vissa webbplatser gör detta avsiktligt för sekundära webbservrar som används för att betjäna resurser. Till exempel kan de ha sin huvudsakliga HTML-sida serverad av en server med en fullständig certifikatechain, men har servrar för resurser som bilder, CSS eller JavaScript inte inkluderar theCA, förmodligen för att spara bandbredd. Tyvärr kan dessa servrar ibland tillhandahållaen webbtjänst som du försöker ringa från din Android-app, vilket inte är lika förlåtande.

det finns två sätt att lösa problemet:

  • konfigurera servern för att inkludera den mellanliggande CA i serverkedjan., De flesta CAs ger dokumentation om hur man gör detta för alla vanliga webbservrar. Detta är det enda tillvägagångssättet om du behöver Webbplatsen att arbeta med standard Android webbläsare åtminstone via Android 4.2.
  • eller, behandla mellanliggande CA som alla andra okända CA, och skapa enTrustManager att lita på det direkt, som gjort i de föregående två avsnitten.

vanliga problem med värdnamnsverifiering

som nämnts i början av den här artikeln finns det två nyckeldelar för att verifiera en SSL-anslutning., Firstis att verifiera certifikatet är från en betrodd källa, som var fokus för previoussection. Fokus för det här avsnittet är den andra delen: se till att servern du ärtalking för att presentera rätt certifikat. När det inte gör det ser du vanligtvis ett felsom detta:

en anledning till att detta kan hända beror på ett serverkonfigurationsfel. Servern ärkonfigurerad med ett certifikat som inte har ett ämne eller ämne alternativt namn fältsom matchar servern du försöker nå. Det är möjligt att få ett certifikat användsmed många olika servrar., Till exempel att titta på google.com certifikat medopenssl s_client -connect google.com:443 | openssl x509 -text du kan se att en subjectthat stöder *.google.com men också föremål alternativa namn för *.youtube.com,*.android.com och andra. Felet uppstår endast när servernamnet du ansluter till inte anges av certifikatet som acceptabelt.

tyvärr kan detta också hända av en annan anledning: virtual hosting. När du delar aserver för mer än ett värdnamn med HTTP, kan webbservern berätta från HTTP / 1.1 requestvilket mål värdnamn klienten letar efter., Tyvärr är detta komplicerat medhttps, eftersom servern måste veta vilket certifikat som ska returneras innan den ser HTTPrequest. För att ta itu med detta problem, nyare versioner av SSL, speciellt TLSv.1.0 och senare, Support Server Name Indication (SNI), vilket gör det möjligt för SSL-klienten att ange intendedhostname till servern så att rätt certifikat kan returneras.

lyckligtvisHttpsURLConnection supportsni sedan Android 2.3. En lösning om du behöver stödja Android 2.,2 (och äldre) är att skapa ett alternativvirtuell värd på en unik port så att det är entydigt vilket servercertifikat som ska returneras.

det mer drastiska alternativet är att ersätta HostnameVerifier med en som inte använder ditt virtuella värdnamn, men den som returneras av servern som standard.

Varning: byte av HostnameVerifierkan vara mycket farligt om den andra virtuella värden inte är under din kontroll, eftersom anon-pathattacker kan styra trafiken till en annanserver utan din vetskap.,

om du fortfarande är säker på att du vill åsidosätta värdnamnsverifiering, här är ett exempelsom ersätter verifieraren för en enda URLConnectionmed en som fortfarande verifierar att värdnamnet åtminstone förväntas av appen:

men kom ihåg, om du befinner dig ersätta värdnamnsverifiering, särskiltpå grund av virtuell värd, är det fortfarande mycket farligt om den andra virtuella värden inte är under din kontroll och du bör hitta en alternativ värdarrangemangsom undviker denna fråga.,

varningar om att använda sslsocket direkt

hittills har exemplen fokuserat på HTTPS medHttpsURLConnection.Ibland behöver appar använda SSL separat från HTTP. Till exempel kan en e-postapp använda SSL variantsof SMTP, POP3 eller IMAP. I dessa fall skulle appen vilja användaSSLSocketdirekt, ungefär på samma sätt somHttpsURLConnection gör internt.

de tekniker som beskrivs sofar för att hantera certifikatverifieringsproblem gäller ävenSSLSocket.,I själva verket, när du använder en anpassad TrustManager, vad skickas tillHttpsURLConnection är en SSLSocketFactory.så om du behöver använda en anpassad TrustManager med enSSLSocket, följsamma steg och Använd att SSLSocketFactory för att skapa dinSSLSocket.

Varning:SSLSocket utför inte verifiering av värdnamn. Det är upp till din app att göra sin egen värdnamnsverifiering, helst genom att ringa getDefaultHostnameVerifier() med det förväntade värdnamnet., Furtherbeware som HostnameVerifier.verify() inte kastar ett undantag på fel utan returnerar istället ett booleskt resultat som du måsteexplicit kontrollera.

här är ett exempel som visar hur du kan göra detta. Det visar att när du ansluter togmail.com port 443 utan SNI-stöd, kommer du att få ett certifikat formail.google.com. Detta förväntas i detta fall, så kontrollera att det intyg är verkligen för mail.google.com:

Denylisting

SSL är starkt beroende av CAs för att utfärda certifikat till endast den ordentligt kontrollerat ownersof servrar och domäner., I sällsynta fall luras CAs antingen eller, när det gäller Comodo eller DigiNotar,bryts, vilket resulterar i att certifikaten för ett värdnamn utfärdas tillnågon annan än ägaren till servern eller domänen.

För att minska denna risk har Android Möjlighet att lägga till vissa certifikat eller evenwhole CAs till en denylist. Medan den här listan historiskt byggdes in i operativsystemet, startingi Android 4.2 kan den här listan uppdateras på distans för att hantera framtida kompromisser.,

Pinning

en app kan ytterligare skydda sig från bedrägligt utfärdade certifikat av atechnique som kallas pinning. Detta använder i grunden exemplet i det okända CA-falletovan för att begränsa en apps betrodda CAs till en liten uppsättning som är känd för att användas av appens servrar. Detta hindrar kompromissen med en av de övriga 100+ CAs i systemet från att resultera i ett brott mot apps secure channel.

klientcertifikat

den här artikeln har fokuserat på användaren av SSL för att säkra kommunikation med servrar., SSL stöder också begreppet klientcertifikat som gör det möjligt för servern att validera identiteten hos aclient. Även utanför tillämpningsområdet för denna artikel, de tekniker som berörs liknar specifiinga anpassade TrustManager.

Nogotofail: ett testverktyg för nätverkstrafiksäkerhet

Nogotofail är ett verktyg som ger dig ett enkelt sätt att bekräfta att dina appar är säkra mot kända TLS / SSL-sårbarheter och missuppfattningar. Det är ett automatiserat, kraftfullt och skalbart verktyg för att testa nätverkssäkerhetsproblem på alla enheter vars nätverkstrafik kan göras för att gå igenom den.,

Nogotofail är användbart för tre huvudsakliga användningsfall:

  • att hitta buggar och sårbarheter.
  • verifiera korrigeringar och titta på regressioner.
  • förstå vilka program och enheter som genererar vilken trafik.

Nogotofail fungerar för Android, iOS, Linux, Windows, Chrome OS, OSX, i själva verket varje enhet som du använder för att ansluta till Internet. Det finns en lättanvänd klient för att konfigurera inställningarna och få meddelanden på Android och Linux, liksom själva attackmotorn som kan distribueras som en router, VPN-server eller proxy.

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *