De Secure Sockets Layer (SSL)—nu technisch bekend als Transport Layer Security(TLS)—is een gemeenschappelijke bouwsteen voor versleutelde communicatie tussen clients en servers. Het is mogelijk dat een applicatie SSL onjuist zou kunnen gebruiken, zodat kwaadaardige entiteiten misschien in staat zijn om gegevens van een app te onderscheppen via het netwerk., Om u te helpen ervoor te zorgen dat dit niet gebeurtento uw app, Dit artikel belicht de gemeenschappelijke valkuilen bij het gebruik van beveiligde netwerkprotocollen en behandelt een aantal grotere zorgen over het gebruik van Public-Key Infrastructure (PKI).
u moet ook AndroidSecurity Overview en PermissionsOverview lezen.
Concepten
In een typisch SSL-gebruiksscenario wordt een server geconfigureerd met een certificaat dat zowel een openbare sleutel als een bijbehorende privésleutel bevat., Als onderdeel van de handshake tussen een SSL clientand server, bewijst de server dat hij de private sleutel heeft door zijn certificaat te ondertekenen met public-key cryptografie.
echter, iedereen kan zijn eigen certificaat en privésleutel genereren, dus een eenvoudige handshake bewijst niets anders over de server dan dat de server de privésleutel kent die overeenkomt met de publieke sleutel van het certificaat. Een manier om dit probleem op te lossen is om de clienthe hebben een set van een of meer certificaten die het vertrouwt. Als het certificaat niet in de set zit, is de server niet te vertrouwen.,
Er zijn verschillende nadelen aan deze eenvoudige benadering. Servers zouden in staat moeten zijn om na verloop van tijd sterkere sleutels aan te passen (“sleutelrotatie”), wat de publieke sleutel in het certificaat vervangt door een nieuwe. Helaas, nu de client app moet worden bijgewerkt als gevolg van whatis in wezen een server configuratie verandering. Dit is vooral problematisch als de server niet onder de controle van de app-ontwikkelaar staat, bijvoorbeeld als het een webservice van derden is. Deze aanpak heeft ook problemen als de app heeft om te praten met willekeurige servers, zoals een webbrowser oremail app.,
om deze nadelen aan te pakken, worden servers doorgaans geconfigureerd met certificaten van bekende emittenten, genaamd Certificate Authorities (Ca ‘ s).Het hostplatform bevat over het algemeen een lijst van bekende Ca ‘ s die het trusts.As van Android 4.2 (Jelly Bean), Android bevat momenteel meer dan 100 CAs die worden bijgewerkt in elke release. Net als een server heeft een CA een certificaat en een private sleutel. Wanneer een certificaat voor een server wordt afgegeven, ondertekent de CA het servercertificaat met de eigen sleutel. De klant kan dan controleren of de server een certificaat heeft dat is uitgegeven door een CA die bekend is bij het platform.,
echter, terwijl het oplossen van een aantal problemen, het gebruik van CAs introduceert een andere. Omdat de CA issuescertificeert voor veel servers, moet je nog steeds een manier om ervoor te zorgen dat je praat met de server die je wilt. Om dit aan te pakken, identificeert het door de CA afgegeven certificaat de server met een specifieke naam, zoals gmail.com of een set hosts met jokertekens zoals *.google.com.
het volgende voorbeeld zal deze concepten wat concreter maken., In het fragment onder een opdrachtregel kijkt het openssl
Gereedschap s_client
commando naar Wikipedia ‘ s server certificaat informatie. Het specificeert poort 443 omdat dat de standaard is voor HTTPS. Het commando verzendt de uitvoer van openssl s_client
naar openssl x509
, die informatie over certificaten formatteert volgens de X. 509-standaard. Specifiek vraagt de opdracht om het onderwerp, dat de servernaaminformatie bevat,en de uitgever, die de CA identificeert.,
u kunt zien dat het certificaat is uitgegeven voor servers die overeenkomen met *.wikipedia.org the RapidSSL CA.
een voorbeeld van HTTPS
aangenomen dat u een webserver hebt met een certificaat uitgegeven door een bekende CA, kunt u een veilig verzoek indienen met de volgende code:
Ja, het kan echt zo eenvoudig zijn. Als u het HTTP-verzoek wilt aanpassen, kunt u casten naaran HttpURLConnection
., De Android documentatie voorHttpURLConnection
bevat meer voorbeelden over hoe om te gaan met Request en response headers, het plaatsen van content, het beheren van cookies, het gebruik van proxy ‘ s, het cachen van reacties,enzovoort. Maar in termen van de details voor het verifiëren van certificaten en hostnamen, de Androidframework zorgt voor u via deze API ‘ s.Dit is waar je wilt zijn als het al mogelijk is. Dat gezegd hebbende, hieronder zijn een aantal andere overwegingen.,
algemene problemen verifiëren van server-certificaten
Stel in plaats van het ontvangen van de inhoud van de getInputStream()
het genereert een uitzondering:
Dit kan gebeuren om verschillende redenen, waaronder:
- De CERTIFICERINGSINSTANTIE die het servercertificaat heeft verleend, was onbekend
- De server certificaat niet is ondertekend door een CA, maar was zelf ondertekend
- De server configuratie ontbreekt een tussenliggende CERTIFICERINGSINSTANTIE
De volgende paragrafen beschrijven hoe deze problemen aan te pakken, terwijl het houden van yourconnection om de server te beveiligen.,
Onbekende certificaatautoriteit
In dit geval treedt deSSLHandshakeException
op omdat u een CA hebt die niet wordt vertrouwd door het systeem. Het kan zijn omdat je een certificaat hebt van een nieuwe CA die nog niet wordt vertrouwd door Android of je app draait op een oudere versie zonder de CA. Vaker is een CA onbekend omdat het geen openbare CA is, maar een privé-CA die is uitgegeven door een organisatie zoals een overheid, bedrijf of onderwijsinstelling voor eigen gebruik.
gelukkig kunt u HttpsURLConnection
leren om een specifieke set Ca ‘ s te vertrouwen., De procedure kan een beetje ingewikkeld zijn, dus hieronder is een voorbeeld dat een specifieke CA neemt van InputStream
, gebruikt om een KeyStore
aan te maken en te initialiseren eenTrustManager
. Een TrustManager
is wat het systeem gebruikt om certificaten van de server te valideren en—door er een aan te maken van een KeyStore
met een of meer CAs—deze zullen de enige Ca ‘ s zijn die door die TrustManager
worden vertrouwd.,
gegeven de nieuwe TrustManager
,initialiseert het voorbeeld een nieuwe SSLContext
die an SSLSocketFactory
geeft die u kunt gebruiken om de standaard te overschrijvenSSLSocketFactory
vanHttpsURLConnection
. Op deze manier gebruikt theconnection uw Ca ‘ s voor certificaatvalidatie.
Hier is het voorbeeld infull met behulp van een organisatie-CA van de Universiteit van Washington:
met een aangepaste TrustManager
die op de hoogte is van uw Ca ‘ s,kan het systeem valideren dat uw servercertificaat afkomstig is van een vertrouwde uitgever.,
Let op:veel websites beschrijven een slechte alternatieve oplossing, namelijk het installeren van eenTrustManager
die niets doet. Als je dit doet kun je net zo goed nietbe versleutelen van uw communicatie, omdat iedereen uw gebruikers kan aanvallen op een openbare Wi-Fi hotspot door het gebruik van DNS trucs om uw gebruikers ‘ Traffic sturen via een proxy van hun eigen die zich voordoet als uw server. De aanvaller kan dan wachtwoorden en andere persoonlijke gegevens opnemen., Dit werkt omdat de aanvaller een certificaat kan genereren en-zonder een TrustManager
die daadwerkelijk valideert dat het certificaat afkomstig is van een trustedsource—kan je app met iedereen praten. Dus doe dit niet, zelfs niet tijdelijk. Je kunt er altijd voor zorgen dat je app de uitgever van het certificaat van de server vertrouwt, dus doe het gewoon.
zelfondertekend servercertificaat
het tweede geval van SSLHandshakeException
is het gevolg van een zelfondertekend certificaat, wat betekent dat de server zich gedraagt als zijn eigen CA.,Dit is vergelijkbaar met een onbekende certificaatautoriteit, dus u kunt dezelfde aanpak uit de vorige sectie gebruiken.
u kunt uw eigen TrustManager
aanmaken,deze keer vertrouwend op het servercertificaat. Dit heeft alle van dedownsides eerder besproken van het koppelen van uw app direct aan een certificaat, maar kan worden donesecurely. Echter, je moet voorzichtig zijn om ervoor te zorgen dat uw zelf-ondertekend certificaat heeft een redelijk sterke sleutel. Vanaf 2012, een 2048-bit RSA handtekening met een exponent van 65537 expiringyearly is aanvaardbaar., Bij het draaien van toetsen, moet u controleren op aanbevelingen van anauthority (zoals NIST) over wat aanvaardbaar is.
ontbrekende intermediaire certificaatautoriteit
het derde geval vanSSLHandshakeException
treedt op als gevolg van een ontbrekende intermediaire CA. De meeste publicca ‘ s ondertekenen servercertificaten niet direct. In plaats daarvan gebruiken ze hun hoofd-CA-certificaat,de root-CA genoemd, om intermediaire Ca ‘ s te ondertekenen. Ze doen dit zodat de root CA storedoffline kan zijn om het risico van compromis te verminderen., Echter, besturingssystemen zoals Android typicallytrust alleen Root CA ‘ s direct,die een korte kloof van vertrouwen tussen het servercertificaat—ondertekend door de tussenliggende CA—en het certificaat verificateur, die de root CA kent laat. Solvethis, de server stuurt de client niet alleen het certificaat tijdens de SSL handshake, maar een keten van certificaten van de server CA via alle tussenpersonen die nodig zijn om een vertrouwde root CA te bereiken.
om te zien hoe dit eruit ziet in de praktijk, hier is de mail.google.,com certificatechain zoals weergegeven door het openssl
s_client
Commando:
Dit toont aan dat de server een certificaat voor mail verzendt.google.afgegeven door de Thawte SGC CA, een intermediaire CA, en een tweede certificaat voor de Thawte SGC CA, afgegeven door een Verisign CA, de primaire CA die door Android wordt gecontroleerd.
Het is echter niet ongewoon om een server zo in te stellen dat de noodzakelijke tussenliggende CA niet wordt opgenomen., Bijvoorbeeld, hier is een server die een fout kan veroorzaken in Android browsers enuitzonderingen in Android apps:
wat interessant is om op te merken is dat het bezoeken van deze server in de meeste desktop browsers Geen Fout Veroorzaakt zoals een volledig onbekende CA of zelfondertekend servercertificaat zou veroorzaken. Dit komt omdat de meeste desktop browsers cache vertrouwde intermediaire CAs na verloop van tijd. Oncea browser heeft bezocht en geleerd over een tussenliggende CA van een site, het zal niet nodig om de tussenliggende CA opgenomen in de certificaatketen de volgende keer.,
sommige sites doen dit opzettelijk voor secundaire webservers die worden gebruikt om bronnen te bedienen. Bijvoorbeeld, ze kunnen hun belangrijkste HTML-pagina geserveerd door een server met een volledige certificatechain, maar hebben servers voor bronnen zoals afbeeldingen, CSS, of JavaScript niet bevatten theCA, vermoedelijk om bandbreedte te besparen. Helaas, soms deze servers kunnen worden providing een webservice die u probeert te bellen vanaf je Android-app, die niet zo vergevingsgezind.
Er zijn twee benaderingen om dit probleem op te lossen:
- Configureer de server om de tussenliggende CA in de serverketen op te nemen., De meeste Ca ‘ s bieden documentatie over hoe dit te doen voor alle gangbare webservers. Dit is de enige aanpak als je de site nodig hebt om te werken met standaard Android browsers ten minste via Android 4.2.
- of, behandel de tussenliggende CA als elke andere onbekende CA, en maak een
TrustManager
om het direct te vertrouwen, zoals gedaan in de vorige twee secties.
veel voorkomende problemen met hostname verificatie
zoals vermeld aan het begin van dit artikel,zijn er twee belangrijke delen om een SSL-verbinding te verifiëren., De eerste is om te controleren of het certificaat afkomstig is van een vertrouwde bron, wat de focus was van de vorige sectie. De focus van deze sectie is het tweede deel: ervoor zorgen dat de server die je aan het praten bent het juiste certificaat presenteert. Als dit niet het geval is, zie je meestal een fout als deze:
een reden waarom dit kan gebeuren is te wijten aan een server configuratie fout. De server is geconfigureerd met een certificaat dat geen subject-of subject-alternatieve naamvelden heeft die overeenkomen met de server die u probeert te bereiken. Het is mogelijk om één certificaat te gebruiken met veel verschillende servers., Bijvoorbeeld, kijkend naar de google.com certificaat metopenssl
s_client -connect google.com:443 | openssl x509 -text
U kunt zien dat een subject dat *ondersteunt.google.com maar ook alternatieve namen voor *.youtube.com,*. android.com en anderen. De fout treedt alleen op als de servernaam waarmee u verbinding maakt, niet door het certificaat wordt vermeld als aanvaardbaar.
helaas kan dit ook om een andere reden gebeuren: virtual hosting. Bij het delen van een server voor meer dan één hostnaam met HTTP, kan de webserver aan de HTTP/1.1 request zien naar welke hostnaam de client op zoek is., Helaas is dit ingewikkeld met https, omdat de server moet weten welk certificaat te retourneren voordat het de HTTPrequest ziet. Om dit probleem aan te pakken, nieuwere versies van SSL, in het bijzonder TLSv.1.0 en later ondersteunt SNI (Server Name Indication), waarmee de SSL-client de gewenste hostnaam kan opgeven voor de server, zodat het juiste certificaat kan worden geretourneerd.
Gelukkig ondersteunt HttpsURLConnection
sinds Android 2.3. Een workaroundif je nodig hebt om Android ondersteunen 2.,2 (en ouder) is het opzetten van een alternatieve evirtual host op een unieke poort, zodat het eenduidig is welk servercertificaat te retourneren.
het meest drastische alternatief is om HostnameVerifier
te vervangen door een systeem dat niet de hostnaam van uw virtuele host gebruikt, maar degene die standaard door de server wordt geretourneerd.
Let op: het vervangen vanHostnameVerifier
kan zeer gevaarlijk zijn als de andere virtuele host niet onder uw controle is, omdat een on-pathattacker zonder uw medeweten verkeer naar een andere server kan leiden.,
Als je nog steeds zeker dat u wilt overschrijven hostnaam verificatie, hier is een examplethat vervangt de verificateur voor één URLConnection
met een die nog steeds wordt gecontroleerd of de hostnaam is ten minste op verwacht door de app:
Maar vergeet niet, als je jezelf vervangen hostnaam verificatie, especiallydue te virtual hosting, het is nog steeds erg gevaarlijk zijn als de andere virtuele host niet onder je controle en je moet zoeken naar een alternatieve hosting arrangementthat voorkomt dit probleem.,
waarschuwingen over het gebruik van SSLSocket direct
tot nu toe zijn de voorbeelden gericht op HTTPS met HttpsURLConnection
.Soms moeten apps SSL apart van HTTP gebruiken. Een e-mailapp kan bijvoorbeeld SSL-varianten van SMTP, POP3 of IMAP gebruiken. In die gevallen zou de app SSLSocket
direct willen gebruiken, net zoals HttpsURLConnection
intern gebruikt.
De tot nu toe beschreven technieken om problemen met de verificatie van certificaten aan te pakken, zijn ook van toepassing op SSLSocket
.,In feite is bij gebruik van een aangepaste TrustManager
, wat wordt doorgegeven aanHttpsURLConnection
een SSLSocketFactory
.dus als u een aangepaste TrustManager
moet gebruiken met eenSSLSocket
, volg dezelfde stappen en gebruik die SSLSocketFactory
om uwSSLSocket
aan te maken.
Let op: SSLSocket
voert geen hostnaam verificatie uit. Het is aan uw app om zijn eigen hostnaam verificatie uit te voeren, bij voorkeur door getDefaultHostnameVerifier()
met de verwachte hostnaam aan te roepen., Verder is het mogelijk dat HostnameVerifier.verify()
geen uitzondering geeft op fouten, maar in plaats daarvan een Booleaans resultaat retourneert dat u expliciet moet controleren.
Hier is een voorbeeld dat laat zien hoe je dit kunt doen. Het laat zien dat bij het verbinden togmail.com poort 443 zonder SNI-ondersteuning ontvangt u een certificaat formail.google.com. dit wordt verwacht in dit geval, dus controleer of het certificaat is inderdaad voor mail.google.com:
Denylisting
SSL is sterk afhankelijk van Ca ‘ s om certificaten uit te geven aan alleen de correct geverifieerde eigenaars van servers en domeinen., In zeldzame gevallen worden CAs ‘ s bedrogen of, in het geval van Comodo of DigiNotar, geschonden, wat resulteert in de certificaten voor een hostnaam die moet worden uitgegeven aan iemand anders dan de eigenaar van de server of het domein.
om dit risico te beperken, heeft Android de mogelijkheid om bepaalde certificaten of zelfs hele Ca ‘ s aan een denylist toe te voegen. Hoewel deze lijst historisch werd ingebouwd in het besturingssysteem, startingin Android 4.2 deze lijst kan op afstand worden bijgewerkt om te gaan met toekomstige compromissen.,
Pinning
een app kan zichzelf verder beschermen tegen frauduleus uitgegeven certificaten door atechnique, bekend als pinning. Dit is in principe met behulp van het voorbeeld in de onbekende CA caseabove om een app vertrouwde CA ‘ s te beperken tot een kleine set bekend te worden gebruikt door de servers van de app. Dit voorkomt dat het compromis van een van de andere 100+ Ca ‘ s in het systeem resulteert in een inbreuk op het apps secure channel.
clientcertificaten
Dit artikel is gericht op de gebruiker van SSL om de communicatie met servers te beveiligen., SSL ondersteunt ook het begrip clientcertificaten waarmee de server de identiteit van aclient kan valideren. Hoewel de betrokken technieken buiten het toepassingsgebied van dit artikel vallen, zijn ze vergelijkbaar met het specificeren van een aangepaste TrustManager
.
Nogotofail: een network traffic security testing tool
Nogotofail is een tool geeft u een gemakkelijke manier om te bevestigen dat uw apps zijn veilig tegen bekende TLS / SSL kwetsbaarheden en misconfiguraties. Het is een geautomatiseerde, krachtige en schaalbare tool voor het testen van netwerkbeveiliging problemen op elk apparaat waarvan het netwerkverkeer kan worden gemaakt om te gaan door het.,
Nogotofail is nuttig voor drie belangrijke use cases:
- het vinden van bugs en kwetsbaarheden.
- fixes verifiëren en kijken naar regressies.
- inzicht in welke toepassingen en apparaten welk verkeer genereren.
Nogotofail werkt voor Android, iOS, Linux, Windows, Chrome OS, OSX, in feite elk apparaat dat u gebruikt om verbinding te maken met het Internet. Er is een eenvoudig te gebruiken client om de instellingen te configureren en meldingen te krijgen op Android en Linux, evenals de aanval engine zelf die kan worden ingezet als een router, VPN-server of proxy.