Secure Sockets Layer (SSL)—nu teknisk kendt som Transport Layer Security(TLS)—er almindelige byggesten for krypteret kommunikation mellem klienter og servere. Det er muligt thatan ansøgning kan bruge SSL forkert, således at ondsindede enheder måske i stand til at opfange en app data over netværket., For at hjælpe dig med at sikre, at dette ikke happento din app, Denne artikel fremhæver de fælles faldgruber, når du bruger sikre netværksprotokoller og løser nogle større bekymringer om at bruge Public-Key infrastruktur (PKI).
Du bør også læse AndroidSecurity oversigt samt Permissionsovervie..
koncepter
i et typisk SSL-brugsscenarie konfigureres en server med et certifikat, der indeholder en offentlig nøgle samt en matchende privat nøgle., Som en del af håndtrykket mellem en SSL-klientog-server beviser serveren, at den har den private nøgle ved at underskrive sit certifikat med kryptografi med offentlig nøgle.
men alle kan generere deres eget certifikat og private nøgle, så en simpel handshakedoesn ‘ t bevise noget om serveren andet end at serveren kender den private nøgle thatmatches den offentlige nøgle af certifikatet. En måde at løse dette problem på er at have klientenhar et sæt af et eller flere certifikater, det stoler på. Hvis certifikatet ikke er i sættet, disserver er ikke at stole på.,
Der er flere ulemper ved denne enkle tilgang. Servere skal kunne opgradere til stærkere nøgler over tid (“key rotation”), som erstatter den offentlige nøgle i certifikatet med en ny. Desværre skal klientappen opdateres på grund af hvader i det væsentlige en serverkonfigurationsændring. Dette er især problematisk, hvis serverener ikke under appudviklerens kontrol, for eksempel hvis det er en tredjeparts webebtjeneste. Thisapproach har også problemer, hvis appen skal tale med vilkårlige servere, såsom en oebbro .ser oremail-app.,
for at løse disse ulemper konfigureres servere typisk med certificatesfra velkendte udstedere kaldet Certificate Authorities (CAs).Værtsplatformen indeholder generelt en liste over velkendte CAs, at den trusts.As af Android 4.2 (Jelly Bean) indeholder Android i øjeblikket over 100 CAs, der opdateres i hver udgivelse. I lighed med en server har en CA et certifikat og en privat nøgle. Når der udstedes et certifikat til en server, signerer CASERVERCERTIFIKATET ved hjælp af sin private nøgle. Theclient kan derefter kontrollere, at serveren har et certifikat udstedt af en CA, der er kendt for platformen.,
men mens du løser nogle problemer, introducerer CAs en anden. Fordi CA udsteder certifikater for mange servere, har du stadig brug for en måde at sikre dig, at du taler med den server, du ønsker. For at løse dette, certifikatet udstedt af CA identificerer servereither med et bestemt navn såsom gmail.com eller et wildildcarded sæt af værter som *.google.com.
følgende eksempel vil gøre disse begreber lidt mere konkrete., I uddraget nedenforfra en kommandolinje ser kommandoen openssl
værktøjets s_client
på serverikipedia ‘ s servercertifikatoplysninger. Itspecifies port 443, fordi det er standard for https. Kommandoen senderudgangen af openssl s_client
til openssl x509
, som formaterer informationom certifikater i henhold til standard. 509-standarden. Specifikt beder kommandoen om emnet, som indeholder servernavnoplysningerne, og udstederen, som identificerer CA.,
Du kan se, at certifikatet blev udstedt for servere, der matcher *.wikipedia.org af RapidSSL CA.
et https eksempel
forudsat at du har en webebserver med acertificate udstedt af en velkendt CA, kan du foretage en sikker anmodning med kode somsimple dette:
Ja, det kan virkelig være så simpelt. Hvis du vil skræddersy HTTP-anmodningen, kan du caste toan HttpURLConnection
., Android-dokumentationen tilHttpURLConnection
har yderligere eksempler på, hvordan man håndterer re .uestand response headers, udstationering af indhold, styring af cookies, brug af fuldmagter,caching-svar og så videre. Men med hensyn til detaljerne for verifikation af certifikater og værtsnavne tager Androidframeworkork sig af det for dig gennem disse API ‘ er.Det er her, du vil være, hvis det overhovedet er muligt. Det sagt, nedenfor er nogle andre overvejelser.,
den Fælles problemer med at kontrollere server certifikater
Antag at i stedet for at modtage indhold fra getInputStream()
, det kaster en undtagelse:
Dette kan ske af forskellige årsager, herunder:
- CA, der har udstedt det servercertifikat, der var ukendt
- serverens certifikat, der ikke var underskrevet af en CA, men var selv underskrevet
- serverens konfiguration mangler en mellemliggende CA
i De følgende afsnit diskutere, hvordan at løse disse problemer, mens du holder yourconnection til serveren sikker.,
ukendt certifikatmyndighed
i dette tilfælde forekommer SSLHandshakeException
fordi du har en CA, der ikke er tillid til af systemet. Det kan skyldes, at du har et certifikat fra en ny CA, der endnu ikke er tillid til af Android, eller din app kører på en ældre version uden CA. Oftere er en CA ukendt, fordi den ikke er enoffentlig CA, men en privat udstedt af en organisation som en regering,selskab eller uddannelsesinstitution til eget brug.heldigvis kan du lære HttpsURLConnection
at stole på et bestemt sæt CAs., Den procedurecan være lidt indviklet, så nedenfor er et eksempel, der tager en bestemt CA froman InputStream
, bruger det til at lave en KeyStore
,som derefter bruges til at oprette og formatere enTrustManager
. TrustManager
er, hvad systemuses at godkende certifikater fra serverog—ved at skabe en fra en KeyStore
med en eller flere CAs—thosewill være den eneste CAs tillid til, at TrustManager
.,
i Betragtning af den nye TrustManager
,eksempel initialiserer en ny SSLContext
, som providesan SSLSocketFactory
du kan bruge til at tilsidesætte standardSSLSocketFactory
fraHttpsURLConnection
. Denne måde theconnection vil bruge din CAs til certifikat validering.
Her er et eksempel infull ved hjælp af en organisatorisk CA fra University of Washington:
Med en brugerdefineret TrustManager
, der ved, om din CAs,systemet er i stand til at validatethat din server certifikatet kommer fra en pålidelig udsteder.,advarsel: mange webebsteder beskriver en dårlig alternativ løsning, som er at installere enTrustManager
, der ikke gør noget. Hvis du gør dette, kan du lige så godt ikke kryptere din kommunikation, fordi enhver kan angribe dine brugere på et offentligt Hoti-Fi-hotspotved at bruge DNS-tricks til at sende dine brugere ikke trafik gennem en egen pro .y, der foregiver at være din server. Angriberen kan derefter registrere adgangskoder og andre personlige data., Dette fungerer, fordi angriberen kan generere et certifikat og – uden et TrustManager
, der faktisk validerer, at certifikatet kommer fra en trustedsource—kan din app tale med nogen. Så gør det ikke, ikke engang midlertidigt. Du Canal .ays gøre din app tillid udstederen af serverens certifikat, så bare gøre det.
selvsigneret servercertifikat
det andet tilfælde af SSLHandshakeException
erPå grund af et selvsigneret certifikat, hvilket betyder, at serveren opfører sig som sin egen CA.,Dette ligner en ukendt certifikatmyndighed, så du kan brugesamme tilgang fra det foregående afsnit.
Du kan oprette din egen TrustManager
,denne gang tillid til servercertifikatet direkte. Dette har alle de do .nsides diskuteret tidligere for at binde din app direkte til et certifikat, men kan donesecurely. Du skal dog være forsigtig med at sikre dig, at dit selvsignerede certifikat har en områdelig stærk nøgle. Fra 2012 er en 2048-bit RSA-signatur med en eksponent på 65537 e .piringyearly acceptabel., Når du roterer nøgler, skal du tjekke for anbefalinger fra enauthority (såsom NIST) om, hvad der er acceptabelt.
manglende mellemliggende certifikatmyndighed
det tredje tilfælde af SSLHandshakeException
opstår på grund af manglende mellemliggende CA. De fleste publicCAs underskriver ikke servercertifikater direkte. I stedet bruger de deres vigtigste CA-certifikat, kaldet root CA, til at underskrive mellemliggende CAs. De gør dette, så root CA kan gemmesoffline for at reducere risikoen for kompromis., Men operativsystemer som Android typiskstol kun root CAs direkte, hvilket efterlader et kort tillid mellem serverencertifikat-underskrevet af den mellemliggende CA—og certifikatverifikatoren,som kender root CA. For at løseDette sender serveren ikke kun klienten, det er certifikat under SSL-håndtrykket, men en kæde af certifikater fra serveren CA gennem eventuelle mellemprodukter, der er nødvendige for at nå atrusted root CA.
for at se, hvordan dette ser ud i praksis, her er mailen.Googles.,com certificatechain som vist afopenssl
s_client
kommando:
Dette viser, at serveren sender et certifikat til mail.Googles.comissued af Thawte-SGC CA, som er en mellemliggende CA, og en anden certificatefor Thawte SGC CA udstedt af Verisign CA, som er den primære CA, at’strusted af Android.
det er dog ikke ualmindeligt at konfigurere en server til ikke at inkludere den necessaryintermediate CA., For eksempel, her er en server, som kan forårsage en fejl i Android browsere andexceptions i Android apps:
Hvad er interessant at bemærke her er, at du besøger denne server i de fleste desktop browsersdoes ikke forårsage en fejl som et helt ukendt CA eller selv-signeret servercertifikat wouldcause. Dette skyldes, at de fleste desktop-bro .sere cache betroede mellemliggende CAs over tid. Oncea bro .ser har besøgt og lært om en mellemliggende CA fra et siteebsted, vil det ikke være nødvendigt at have den mellemliggende CA inkluderet i certifikatkæden næste gang.,nogle sitesebsteder gør dette med vilje for sekundære webebservere, der bruges til at betjene ressourcer. Fore .ample, de kan have deres vigtigste HTML-side betjenes af en server med en fuld certificatechain, men har servere for ressourcer såsom billeder, CSS, eller JavaScript ikke omfatter theCA, formentlig for at spare båndbredde. Desværre kan nogle gange disse servere levereen webebtjeneste, du forsøger at ringe fra din Android-app, hvilket ikke er så tilgivende.
Der er to metoder til at løse dette problem:
- Konfigurer serveren til at inkludere den mellemliggende CA i serverkæden., De fleste CAs leverer dokumentation om, hvordan man gør dette for alle almindelige webebservere. Dette er den eneste tilgang, hvis du har brug for siteebstedet til at arbejde med standard Android-bro .sere i det mindste gennem Android 4.2.
- eller behandl den mellemliggende CA som enhver anden ukendt CA, og opret en
TrustManager
for at stole på det direkte, som gjort i de to foregående afsnit.
almindelige problemer med værtsnavn verifikation
Som nævnt i begyndelsen af denne artikel er der to vigtige dele til at verificere en SSL-forbindelse., Den første til at verificere certifikatet er fra en betroet kilde, som var fokus for det foregående afsnit. Fokus for dette afsnit er den anden del: sørg for, at den server, du taler til, præsenterer det rigtige certifikat. Når det ikke sker, vil du typisk se en fejlligesom dette:
en af grundene til, at dette kan ske, skyldes en serverkonfigurationsfejl. Serveren konfigureres med et certifikat, der ikke har et emne eller emne alternativt navnefelter, der matcher den server, du forsøger at nå. Det er muligt at få et certifikat brugtmed mange forskellige servere., For eksempel ser man på google.com certifikat medopenssl
s_client -connect google.com:443 | openssl x509 -text
du kan se, at et emne, der understøtter *.google.com men også emne alternative navne til*. youtube.com,*.android.com, og andre. Fejlen opstår kun, når servernavnet youare forbinder til, ikke er angivet af certifikatet som acceptabelt.
desværre kan dette også ske af en anden grund: virtuel hosting. Når du deler aserver for mere end et værtsnavn med HTTP, kan webebserveren fortælle fra HTTP/1.1-anmodningenhvilket målværtnavn klienten leder efter., Desværre er dette kompliceret medhttps, fordi serveren skal vide, hvilket certifikat der skal returneres, før det ser Httpre .uest. For at løse dette problem, nyere versioner af SSL, specifikt TLSv.1.0 og senere, support Server Name indikation (SNI), som gør det muligt for SSL-klienten at angive intendedhostname til serveren, så det korrekte certifikat kan returneres.
Heldigvis HttpsURLConnection
supportsSNI siden Android 2.3. En workorkaroundhvis du har brug for at understøtte Android 2.,2 (og ældre) er at oprette en alternativevirtual vært på en unik port, så det er entydigt, hvilket servercertifikat der skal returneres.
det mere drastiske alternativ er at erstatte HostnameVerifier
med en, der ikke bruger hostnavnet på din virtuelle vært, men den, der returneres af serveren som standard.
Forsigtighed: Udskiftning HostnameVerifier
kan være meget farlige, hvis de andre virtuelle vært erikke er under din kontrol, fordi anon-pathattacker kunne dirigere trafik til anotherserver uden din viden.,
Hvis du stadig er sikker på, at du vil tilsidesætte værtsnavnsbekræftelse, er her et eksempel, der erstatter verifikatoren for en enkelt URLConnection
med en, der stadig verificerer, at værtsnavnet i det mindste forventes af appen:
men husk, hvis du finder dig selv at erstatte værtsnavnsbekræftelse, især på grund af virtuel hosting, er det stadig meget farligt, hvis den anden virtuelle vært ikke er under din kontrol, og du skal finde en alternativ hostingarrangement, der undgår dette spørgsmål.,
advarsler om brug af sslsocket direkte
indtil videre har eksemplerne fokuseret på HTTPS ved hjælp afHttpsURLConnection
.Nogle gange skal apps bruge SSL adskilt fra http. For eksempel kan en e-mail-app bruge SSL-variantsof SMTP, POP3 eller IMAP. I disse tilfælde vil appen bruge SSLSocket
direkte, meget på samme måde som HttpsURLConnection
gør internt.
de teknikker, der er beskrevet i forbindelse med certifikatverifikationsproblemer, gælder også forSSLSocket
.,I virkeligheden, når du bruger en brugerdefineret TrustManager
, hvad er gået tilHttpsURLConnection
er et SSLSocketFactory
.Så hvis du skal bruge en brugerdefineret TrustManager
medSSLSocket
, followthe samme trin og bruge det SSLSocketFactory
for at oprette dinSSLSocket
.
forsigtig:SSLSocket
udfører ikke værtsnavn verifikation. Det er op til din app til at gøre sin egen værtsnavn verifikation, helst ved at kalde getDefaultHostnameVerifier()
med den forventede værtsnavn., Yderligere at HostnameVerifier.verify()
ikke kaster en undtagelse på fejl, men i stedet returnerer et boolesk resultat, som du must e .plicit kontrollere.
Her er et eksempel, der viser, hvordan du kan gøre dette. Det viser, at når du tilslutter togmail.com port 443 uden SNI støtte, vil du modtage et certifikat formail.google.com. Det forventes i denne sag, så tjek for at gøre sikker på, at certifikatet faktisk for mail.google.com:
Denylisting
SSL er stærkt afhængig af CAs til at udstede certifikater til kun korrekt verificeret ownersof servere og domæner., I sjældne tilfælde, CAs er enten lokket eller, i tilfælde af Comodo eller DigiNotar, overtrådt,resulterer i certifikater for et værtsnavn, der skal udstedes tilen anden end ejeren af serveren eller domænet.
for at mindske denne risiko, Android har evnen til at tilføje visse certifikater eller enddahele CAs til en denylist. Mens denne liste historisk blev indbygget i operativsystemet, starteri Android 4.2 denne liste kan opdateres eksternt for at håndtere fremtidige kompromiser.,
Pinning
en app kan yderligere beskytte sig mod svigagtigt udstedte certifikater af atechni .ue kendt som pinning. Dette er dybest set ved hjælp af eksemplet i det ukendte CA caseabove at begrænse en app betroede CAs til et lille sæt kendt for at blive brugt af appens servere. Thisprevents kompromis af en af de andre 100 + CAs i systemet fra resulterer i et brud på apps sikker kanal.
klientcertifikater
Denne artikel har fokuseret på brugeren af SSL til at sikre kommunikation med servere., SSL ogsåunderstøtter begrebet klientcertifikater, der giver serveren mulighed for at validere aclients identitet. Uden for rammerne af denne artikel svarer de involverede teknikker til at specificereen brugerdefineret TrustManager
.
Nogotofail: et testværktøj til netværkstrafik
Nogotofail er et værktøj, der giver dig en nem måde at bekræfte, at dine apps er sikre mod kendte TLS / SSL-sårbarheder og fejlkonfigurationer. Det er et automatiseret, kraftfuldt og skalerbart værktøj til test af netværkssikkerhedsproblemer på enhver enhed, hvis netværkstrafik kunne gøres for at gennemgå det.,
Nogotofail er nyttigt for tre primære use cases:
- finde fejl og sårbarheder.
- verificerer rettelser og ser på regressioner.
- forstå, hvilke applikationer og enheder der genererer hvilken trafik.
Nogotofail virker til Android, iOS, Linux, Windows, Chrome OS, OSX, faktisk enhver enhed, du bruger til at oprette forbindelse til Internettet. Der er en brugervenlig klient til at konfigurere indstillingerne og få meddelelser på Android og Linu.samt selve angrebsmotoren, der kan implementeres som en router, VPN-server eller pro .y.