Heim >System-Tutorial >LINUX >Analysieren Sie die Prinzipien von HTTPS und seine Verwendung in Android

Analysieren Sie die Prinzipien von HTTPS und seine Verwendung in Android

王林
王林nach vorne
2024-02-23 08:00:211102Durchsuche
1. Mängel des HTTP-Protokolls

Wenn HTTP1.x Daten überträgt, liegen alle übertragenen Inhalte im Klartext vor. Weder der Client noch der Server können die Identität der anderen Partei überprüfen. Die bestehenden Probleme sind wie folgt:

  • Die Kommunikation erfolgt im Klartext (nicht verschlüsselt) und der Inhalt kann abgehört werden;
  • Wenn Sie die Identität der kommunizierenden Partei nicht überprüfen, kann es zu einer Tarnung kommen;
  • Die Integrität der Nachricht kann nicht nachgewiesen werden, daher wurde sie möglicherweise manipuliert;

Tatsächlich treten diese Probleme nicht nur bei HTTP auf, sondern auch bei anderen unverschlüsselten Protokollen.

(1) Kommunikation im Klartext kann abgehört werden

Gemäß dem Funktionsmechanismus der TCP/IP-Protokollsuite besteht die Gefahr, dass Kommunikationsinhalte überall im Internet abgehört werden. Das HTTP-Protokoll selbst verfügt nicht über die Verschlüsselungsfunktion und alle übertragenen Daten sind Klartext. Selbst wenn die Kommunikation verschlüsselt wurde, wird der Kommunikationsinhalt eingesehen, was mit der unverschlüsselten Kommunikation identisch ist. Dies bedeutet lediglich, dass es bei verschlüsselter Kommunikation möglicherweise unmöglich ist, die Bedeutung der Nachrichteninformationen zu entschlüsseln, die verschlüsselte Nachricht selbst jedoch weiterhin sichtbar ist.

(2) Das Versäumnis, die Identität der kommunizierenden Partei zu überprüfen, kann zu einer Verschleierung führen

Da während der HTTP-Protokollkommunikation keine Verarbeitungsschritte zur Bestätigung der kommunizierenden Partei erforderlich sind, kann jeder eine Anfrage initiieren. Darüber hinaus gibt der Server, solange er die Anfrage empfängt, eine Antwort zurück, unabhängig davon, wer die andere Partei ist. Wenn die Kommunikationspartei nicht bestätigt wird, lauern daher folgende versteckte Gefahren:

  • Es ist unmöglich festzustellen, ob der Webserver, an den die Anfrage gesendet wird, derjenige ist, der die Antwort gemäß der wahren Absicht zurückgibt. Möglicherweise handelt es sich um einen getarnten Webserver;
  • Es gibt keine Möglichkeit festzustellen, ob der Client, an den die Antwort zurückgegeben wird, derjenige ist, der die Antwort wie beabsichtigt erhalten hat. Möglicherweise handelt es sich um einen getarnten Kunden;
  • Es ist nicht möglich festzustellen, ob die andere Partei, mit der Sie kommunizieren, Zugriffsrechte hat. Da einige Webserver wichtige Informationen speichern, möchten sie nur bestimmten Benutzern Kommunikationsberechtigungen erteilen;
  • Es ist unmöglich festzustellen, woher die Anfrage kam und wer sie gestellt hat;
  • Selbst bedeutungslose Anfragen werden wie befohlen angenommen und können DoS-Angriffe bei massiven Anfragen nicht verhindern;

(3) Die Integrität der Nachricht kann nicht nachgewiesen werden und sie wurde möglicherweise manipuliert

Die sogenannte Vollständigkeit bezieht sich auf die Richtigkeit von Informationen. Wenn die Vollständigkeit nicht nachgewiesen werden kann, kann in der Regel nicht beurteilt werden, ob die Informationen korrekt sind. Das HTTP-Protokoll kann die Integrität der Kommunikationsnachrichten nicht nachweisen. In der Zeit nach dem Senden der Anfrage oder Antwort bis zum Empfang durch die andere Partei gibt es keine Möglichkeit festzustellen, ob der Inhalt der Anfrage oder Antwort manipuliert wurde.

Beim Herunterladen von Inhalten von einer Website ist es beispielsweise unmöglich festzustellen, ob die vom Client heruntergeladenen Dateien und die auf dem Server gespeicherten Dateien konsistent sind. Möglicherweise wurde der Dateiinhalt während der Übertragung mit anderen Inhalten manipuliert. Selbst wenn sich der Inhalt tatsächlich geändert hat, ist sich dies für den Kunden als Empfänger nicht bewusst. So wird ein Angriff, bei dem die Anfrage oder Antwort vom Angreifer abgefangen und der Inhalt während der Übertragung manipuliert wird, Man-in-the-Middle-Angriff (MITM) genannt.

分析 HTTPS 原理以及在 Android 中的使用

(4) Mehrere Eigenschaften, die eine sichere HTTP-Version haben sollte

Aufgrund der oben genannten Probleme ist eine HTTP-Sicherheitstechnologie erforderlich, die die folgenden Funktionen bereitstellen kann:

(1) Serverauthentifizierung (Clients wissen, dass sie mit einem echten Server und nicht mit einem gefälschten Server sprechen);

(2) Client-Authentifizierung (Server wissen, dass sie mit einem echten Client und nicht mit einem gefälschten Client sprechen);

(3) Integrität (Daten auf Client und Server werden nicht verändert);

(4) Verschlüsselung (die Konversation zwischen Client und Server ist privat, es besteht kein Grund zur Sorge, abgehört zu werden);

(5) Effizienz (ein Algorithmus, der schnell genug läuft, um von Low-End-Clients und -Servern verwendet zu werden);

(6) Universalität (grundsätzlich unterstützen alle Clients und Server diese Protokolle);

2.Schlüsseltechnologien von HTTPS

Im Kontext dieser Nachfrage wurde die HTTPS-Technologie geboren. Die Hauptfunktionen des HTTPS-Protokolls basieren im Wesentlichen auf dem TLS/SSL-Protokoll, das Authentifizierungs-, Informationsverschlüsselungs- und Integritätsüberprüfungsfunktionen bereitstellt, die die Sicherheitsprobleme von HTTP lösen können. Dieser Abschnitt konzentriert sich auf mehrere wichtige technische Punkte des HTTPS-Protokolls.

分析 HTTPS 原理以及在 Android 中的使用

(1) Verschlüsselungstechnologie

Verschlüsselungsalgorithmen werden im Allgemeinen in zwei Typen unterteilt:

Symmetrische Verschlüsselung: Der Schlüssel für die Ver- und Entschlüsselung ist derselbe. Dargestellt durch den DES-Algorithmus;

Asymmetrische Verschlüsselung: Die Schlüssel zur Ver- und Entschlüsselung sind unterschiedlich. Dargestellt durch den RSA-Algorithmus;

Symmetrische Verschlüsselung ist sehr stark und kann im Allgemeinen nicht geknackt werden. Ein großes Problem besteht jedoch darin, dass der Schlüssel nicht sicher generiert und gespeichert werden kann. Wenn jede Sitzung zwischen dem Client und dem Server einen festen, gleichen Schlüssel für die Verschlüsselung und Entschlüsselung verwendet, muss dies der Fall sein große Sicherheitsrisiken darstellen.

Vor dem Aufkommen asymmetrischer Schlüsselaustauschalgorithmen bestand ein großes Problem bei der symmetrischen Verschlüsselung darin, nicht zu wissen, wie Schlüssel sicher generiert und gespeichert werden. Der asymmetrische Schlüsselaustauschprozess dient hauptsächlich dazu, dieses Problem zu lösen und die Generierung und Verwendung von Schlüsseln sicherer zu machen. Aber es ist auch der „Übeltäter“, der die HTTPS-Leistung und -Geschwindigkeit erheblich beeinträchtigt.

HTTPS verwendet einen hybriden Verschlüsselungsmechanismus, der sowohl symmetrische als auch asymmetrische Verschlüsselung im Schlüsselaustauschprozess und symmetrische Verschlüsselung in den nachfolgenden Kommunikations- und Nachrichtenaustauschphasen verwendet.

(2) Authentifizierung – Zertifikat zum Nachweis der Richtigkeit des öffentlichen Schlüssels

Eines der größten Probleme bei der asymmetrischen Verschlüsselung besteht darin, dass sie nicht beweisen kann, dass der öffentliche Schlüssel selbst der echte öffentliche Schlüssel ist. Wenn Sie beispielsweise die Kommunikation mit einem bestimmten Server mithilfe der Verschlüsselung mit öffentlichem Schlüssel vorbereiten, müssen Sie nachweisen, dass der empfangene öffentliche Schlüssel der vom ursprünglich erwarteten Server ausgegebene öffentliche Schlüssel ist. Möglicherweise wurde während der Übertragung des öffentlichen Schlüssels der echte öffentliche Schlüssel durch den Angreifer ersetzt.

Wenn die Zuverlässigkeit des öffentlichen Schlüssels nicht überprüft wird, treten mindestens die folgenden zwei Probleme auf: Man-in-the-Middle-Angriff und Informationsverweigerung.

分析 HTTPS 原理以及在 Android 中的使用

Um die oben genannten Probleme zu lösen, können Sie öffentliche Schlüsselzertifikate verwenden, die von Zertifizierungsstellen für digitale Zertifikate (CA, Certificate Authority) und den damit verbundenen Agenturen ausgestellt wurden.

分析 HTTPS 原理以及在 Android 中的使用

Der spezifische Prozess für die Verwendung von CA ist wie folgt:

(1) Der Serverbetreiber beantragt einen öffentlichen Schlüssel bei der Zertifizierungsstelle (CA) für digitale Zertifikate;

(2) CA überprüft die Authentizität der vom Antragsteller online, offline und auf andere Weise bereitgestellten Informationen, z. B. ob die Organisation existiert, ob das Unternehmen legal ist, ob es Eigentümer des Domainnamens ist usw.;

(3) Wenn die Informationen genehmigt werden, signiert die Zertifizierungsstelle den angewendeten öffentlichen Schlüssel digital, verteilt dann den signierten öffentlichen Schlüssel, fügt den öffentlichen Schlüssel in das Zertifikat des öffentlichen Schlüssels ein und bindet es zusammen. Das Zertifikat enthält die folgenden Informationen: den öffentlichen Schlüssel des Antragstellers, die organisatorischen Informationen und persönlichen Informationen des Antragstellers, die Informationen der ausstellenden Behörde CA, die Gültigkeitsdauer, die Seriennummer des Zertifikats und weitere Informationen im Klartext sowie eine Signatur Signaturgenerierungsalgorithmus: Verwenden Sie zunächst den Hash. Die Spaltenfunktion berechnet den Informationsauszug der öffentlichen Klartextinformationen und verwendet dann den privaten Schlüssel der Zertifizierungsstelle, um den Informationsauszug zu verschlüsseln, und der Chiffretext ist die Signatur;

(4) Der Client sendet während der HTTPS-Handshake-Phase eine Anfrage an den Server und fordert den Server auf, die Zertifikatsdatei zurückzugeben;

(5) Der Client liest die relevanten Klartextinformationen im Zertifikat, berechnet mit derselben Hash-Funktion den Informationsauszug, entschlüsselt dann mit dem öffentlichen Schlüssel der entsprechenden Zertifizierungsstelle die Signaturdaten und vergleicht den Informationsauszug des Zertifikats. Wenn es konsistent ist, kann es die Legitimität des Zertifikats bestätigen, das heißt, der öffentliche Schlüssel ist legitim;

(6) Der Kunde überprüft dann die Informationen zum Domänennamen, die Gültigkeitsdauer und andere Informationen im Zusammenhang mit dem Zertifikat;

(7) Der Client verfügt über integrierte vertrauenswürdige CA-Zertifikatinformationen (einschließlich öffentlichem Schlüssel). Wenn die CA nicht vertrauenswürdig ist, wird das der CA entsprechende Zertifikat nicht gefunden und das Zertifikat wird als illegal beurteilt.

Achten Sie bei diesem Vorgang auf einige Punkte:

(1) Bei der Beantragung eines Zertifikats muss kein privater Schlüssel angegeben werden, wodurch sichergestellt wird, dass der private Schlüssel für immer nur vom Server verwaltet werden kann;

(2) Die Gültigkeit des Zertifikats hängt weiterhin vom asymmetrischen Verschlüsselungsalgorithmus ab. Das Zertifikat fügt hauptsächlich Serverinformationen und Signaturen hinzu;

(3) Das der integrierten Zertifizierungsstelle entsprechende Zertifikat wird als Stammzertifikat bezeichnet. Der Aussteller und der Benutzer sind identisch und sie signieren für sich selbst, was als selbstsigniertes Zertifikat bezeichnet wird

(4) Zertifikat = öffentlicher Schlüssel + Antragsteller- und Ausstellerinformationen + Signatur

3.HTTPS-Protokollprinzip

(1) Geschichte von HTTPS

Einführung in den HTTPS-Protokollverlauf:

  • (1) Die erste Version des SSL-Protokolls wurde von Netscape entwickelt, aber diese Version wurde nie veröffentlicht;
  • (2) Die zweite Version des SSL-Protokolls wurde im November 1994 veröffentlicht. Die erste Bereitstellung erfolgte auf dem Browser Netscape Navigator 1.1, der im März 1995 veröffentlicht wurde;
  • (3) SSL 3 wurde Ende 1995 veröffentlicht. Obwohl der Name mit dem der früheren Protokollversion identisch ist, handelt es sich bei SSL3 um ein völlig neu gestaltetes Protokoll, und das Design wird noch heute verwendet.
  • (4) TLS 1.0 kam im Januar 1999 heraus. Im Vergleich zu SSL 3 sind die Versionsänderungen nicht wesentlich;
  • (5) Im April 2006 wurde die nächste Version TLS 1.1 veröffentlicht, die nur einige wichtige Sicherheitsprobleme behebt;
  • (6) Im August 2008 wurde TLS1.2 veröffentlicht. Diese Version fügt Unterstützung für authentifizierte Verschlüsselung hinzu und entfernt im Wesentlichen alle fest codierten Sicherheitsprimitiven aus der Protokollbeschreibung, wodurch das Protokoll vollständig belastbar ist

(2) Protokollimplementierung

Makroskopisch wird TLS durch das Aufzeichnungsprotokoll implementiert. Das Record-Protokoll ist für den Austausch aller Low-Level-Nachrichten über die Transportverbindung verantwortlich und kann zur Verschlüsselung konfiguriert werden. Jeder TLS-Eintrag beginnt mit einem kurzen Header. Der Header enthält den Typ (oder das Unterprotokoll), die Protokollversion und die Länge des Datensatzinhalts. Die Nachrichtendaten folgen dem Header, wie unten gezeigt:

分析 HTTPS 原理以及在 Android 中的使用

Die TLS-Master-Spezifikation definiert vier Kern-Unterprotokolle:

  • Handshake-Protokoll;
  • Verschlüsselungsspezifikationsprotokoll ändern;
  • Anwendungsdatenprotokoll;
  • Alarmprotokoll;

(3) Handshake-Vereinbarung

Der Handshake ist der ausgefeilteste Teil des TLS-Protokolls. Während dieses Prozesses verhandeln die kommunizierenden Parteien Verbindungsparameter und führen eine vollständige Identitätsauthentifizierung durch. Abhängig von den genutzten Funktionen erfordert der gesamte Prozess in der Regel den Austausch von 6 bis 10 Nachrichten. Abhängig von der Konfiguration und den unterstützten Protokollerweiterungen kann es viele Variationen des Austauschprozesses geben. Folgende drei Prozesse sind im Einsatz häufig zu beobachten:

  • (1) Vollständiger Handshake zur Authentifizierung des Servers (einseitige Authentifizierung, am häufigsten);
  • (2) Handshake, der sowohl Client als auch Server authentifiziert (bidirektionale Authentifizierung);
  • (3) Kurzer Handschlag zum Wiederherstellen der vorherigen Sitzung;

(4) Einweg-Verifizierungs-Handshake-Prozess

In diesem Abschnitt wird der Anmeldevorgang des QQ-Postfachs als Beispiel verwendet, um den Handshake-Prozess der Einwegüberprüfung durch Paketerfassung zu analysieren. Ein vollständiger Handshake-Prozess für die einseitige Verifizierung sieht wie folgt aus:

分析 HTTPS 原理以及在 Android 中的使用

Es ist hauptsächlich in vier Schritte unterteilt:

  • (1) Tauschen Sie die jeweils unterstützten Funktionen aus und vereinbaren Sie die erforderlichen Verbindungsparameter;
  • (2) Überprüfen Sie das vorgelegte Zertifikat oder verwenden Sie andere Methoden zur Authentifizierung;
  • (3) Vereinbaren Sie den gemeinsamen Hauptschlüssel, der zum Schutz der Sitzung verwendet wird;
  • (4) Überprüfen Sie, ob die Handshake-Nachricht von einem Dritten geändert wurde;

Dieser Prozess wird im Folgenden im Detail analysiert.

1.KundeHallo

Im Handshake-Prozess ist ClientHello die erste Nachricht. Diese Nachricht übermittelt die Fähigkeiten und Präferenzen des Clients an den Server. Enthält die angegebene vom Client unterstützte SSL-Version und eine Cipher Suite-Liste (verwendeter Verschlüsselungsalgorithmus, Schlüssellänge usw.).

分析 HTTPS 原理以及在 Android 中的使用

2.ServerHallo

ServerHello-Nachricht überträgt die vom Server ausgewählten Verbindungsparameter zurück an den Client. Die Struktur dieser Nachricht ähnelt der von ClientHello, mit der Ausnahme, dass jedes Feld nur eine Option enthält. Der Inhalt und die Komprimierungsmethode der Verschlüsselungskomponente des Servers werden alle aus den empfangenen Client-Verschlüsselungskomponenten herausgefiltert.

分析 HTTPS 原理以及在 Android 中的使用

3.Zertifikat

Dann sendet der Server eine Zertifikatsnachricht, die das öffentliche Schlüsselzertifikat enthält. Der Server muss sicherstellen, dass das von ihm gesendete Zertifikat mit der ausgewählten Algorithmensuite übereinstimmt. Die Zertifikatsmeldung ist jedoch optional, da nicht alle Pakete eine Authentifizierung verwenden und nicht alle Authentifizierungsmethoden Zertifikate erfordern.

分析 HTTPS 原理以及在 Android 中的使用

4.ServerKeyExchange

Der Zweck der ServerKeyExchange-Nachricht besteht darin, zusätzliche Daten für den Schlüsselaustausch zu übertragen. Der Nachrichteninhalt unterscheidet sich je nach Verhandlungsalgorithmus-Suite. In einigen Szenarios muss der Server nichts senden, und in diesen Szenarios ist es nicht erforderlich, eine ServerKeyExchange-Nachricht zu senden.

分析 HTTPS 原理以及在 Android 中的使用

5.ServerHelloDone

Die

ServerHelloDone-Nachricht zeigt an, dass der Server das Senden aller erwarteten Handshake-Nachrichten abgeschlossen hat. Danach wartet der Server darauf, dass der Client die Nachricht sendet.

分析 HTTPS 原理以及在 Android 中的使用

6.ClientKeyExchange

Die

ClientKeyExchange-Nachricht enthält alle vom Client für den Schlüsselaustausch bereitgestellten Informationen. Diese Nachricht wird von der ausgehandelten Verschlüsselungssuite beeinflusst und der Inhalt variiert je nach ausgehandelter Verschlüsselungssuite.

分析 HTTPS 原理以及在 Android 中的使用

7.ChangeCipherSpec

Die

ChangeCipherSpec-Nachricht zeigt an, dass der Absender ausreichende Informationen zum Generieren von Verbindungsparametern erhalten hat, einen Verschlüsselungsschlüssel generiert hat und in den Verschlüsselungsmodus wechseln wird. Sowohl der Client als auch der Server senden diese Nachricht, wenn die Bedingungen erfüllt sind. Hinweis: ChangeCipherSpec gehört nicht zur Handshake-Nachricht. Es handelt sich um ein anderes Protokoll mit nur einer Nachricht, das als Unterprotokoll implementiert ist.

分析 HTTPS 原理以及在 Android 中的使用

8.Fertig

Fertigmeldung bedeutet, dass der Handshake abgeschlossen ist. Der Nachrichteninhalt wird verschlüsselt, sodass beide Parteien die zur Überprüfung der Integrität des gesamten Handshakes erforderlichen Daten sicher austauschen können. Sowohl der Client als auch der Server senden diese Nachricht, wenn die Bedingungen erfüllt sind.

(5) Handshake-Prozess der bidirektionalen Verifizierung

In einigen Szenarien mit höheren Sicherheitsanforderungen kann die Notwendigkeit einer bidirektionalen Überprüfung entstehen. Der vollständige bidirektionale Verifizierungsprozess läuft wie folgt ab:

分析 HTTPS 原理以及在 Android 中的使用

Sie können sehen, dass die bidirektionale Verifizierung im Vergleich zum einseitigen Verifizierungsprozess die folgenden zwei weiteren Meldungen enthält: CertificateRequest und CertificateVerify. Der Rest des Prozesses ist ungefähr derselbe.

1.Zertifikatsanfrage

Certificate Request ist eine optionale Funktion, die von TLS spezifiziert wird und vom Server zur Authentifizierung der Client-Identität verwendet wird. Wird dadurch implementiert, dass der Server den Client auffordert, ein Zertifikat zu senden. Der Server sollte unmittelbar nach ServerKeyExchange eine CertificateRequest-Nachricht senden.

Die Nachrichtenstruktur ist wie folgt:

enum { 
    rsa_sign(1), dss_sign(2), rsa_fixed_dh(3),dss_fixed_dh(4), 
    rsa_ephemeral_dh_RESERVED(5),dss_ephemeral_dh_RESERVED(6), 
    fortezza_dms_RESERVED(20), 
    ecdsa_sign(64), rsa_fixed_ecdh(65), 
    ecdsa_fixed_ecdh(66),  
    (255) 
} ClientCertificateType; 

opaque DistinguishedName<1..2^16-1>;struct { 
    ClientCertificateType certificate_types<1..2^8-1>; 
    SignatureAndHashAlgorithm 
      supported_signature_algorithms<2^16-1>; 
    DistinguishedName certificate_authorities<0..2^16-1>; 
} CertificateRequest;

Sie können optional eine Liste der akzeptierten Zertifizierungsstellen senden, dargestellt durch deren eindeutige Namen.

2.CertificateVerify

Wenn eine Client-Authentifizierung erforderlich ist, sendet der Client eine CertificateVerify-Nachricht, um zu beweisen, dass er tatsächlich über den privaten Schlüssel des Client-Zertifikats verfügt. Diese Nachricht wird nur gesendet, wenn das Client-Zertifikat über Signaturfunktionen verfügt. CertificateVerify muss ClientKeyExchange unmittelbar folgen. Die Nachrichtenstruktur ist wie folgt:

struct {  
Signature handshake_messages_signature;  
} CertificateVerify;

(6) Anwendungsdatenprotokoll

Das Anwendungsdatenprotokoll überträgt Anwendungsnachrichten. Aus Sicht von TLS sind dies die Datenpuffer. Die Aufzeichnungsschicht verpackt, defragmentiert und verschlüsselt diese Nachrichten unter Verwendung der aktuellen Verbindungssicherheitsparameter. Wie in der folgenden Abbildung dargestellt, können Sie erkennen, dass die übertragenen Daten verschlüsselt wurden.

分析 HTTPS 原理以及在 Android 中的使用

(7) Alarmprotokoll

Der Zweck des Alarms besteht darin, den Peer über einen einfachen Benachrichtigungsmechanismus über abnormale Kommunikationsbedingungen zu informieren. Es enthält normalerweise eine close_notify-Ausnahme, die verwendet wird, wenn die Verbindung geschlossen wird, um Fehler zu melden. Benachrichtigungen sind sehr einfach und bestehen nur aus zwei Feldern:

struct {  
    AlertLevel level;  
    AlertDescription description;  
} Alert;
  • AlertLevel-Feld: Gibt den Schweregrad der Warnung an;
  • AlertDescription: stellt direkt den Alarmcode dar;
4. Häufig gestellte Fragen zur Verwendung von HTTPS in Android

(1) 服务器证书验证错误

这是最常见的一种问题,通常会抛出如下类型的异常:

分析 HTTPS 原理以及在 Android 中的使用

出现此类错误通常可能由以下的三种原因导致:

  • (1) 颁发服务器证书的CA未知;
  • (2) 服务器证书不是由CA签署的,而是自签署(比较常见);
  • (3) 服务器配置缺少中间 CA;

当服务器的CA不被系统信任时,就会发生 SSLHandshakeException。可能是购买的CA证书比较新,Android系统还未信任,也可能是服务器使用的是自签名证书(这个在测试阶段经常遇到)。

解决此类问题常见的做法是:指定HttpsURLConnection信任特定的CA集合。在本文的第5部分代码实现模块,会详细的讲解如何让Android应用信任自签名证书集合或者跳过证书校验的环节。

(2) 域名验证失败

SSL连接有两个关键环节。首先是验证证书是否来自值得信任的来源,其次确保正在通信的服务器提供正确的证书。如果没有提供,通常会看到类似于下面的错误:

分析 HTTPS 原理以及在 Android 中的使用

出现此类问题的原因通常是由于服务器证书中配置的域名和客户端请求的域名不一致所导致的。

有两种解决方案:

(1) 重新生成服务器的证书,用真实的域名信息;

(2) 自定义HostnameVerifier,在握手期间,如果URL的主机名和服务器的标识主机名不匹配,则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。可以通过自定义HostnameVerifier实现一个白名单的功能。

代码如下:

HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() { 
  @Override 
  public boolean verify(String hostname, SSLSession session) { 
    // 设置接受的域名集合 
    if (hostname.equals(...))  { 
         return true; 
    } 
  } 
}; 

HttpsURLConnection.setDefaultHostnameVerifier(DO_NOT_VERIFY);

(3) 客户端证书验证

SSL支持服务端通过验证客户端的证书来确认客户端的身份。这种技术与TrustManager的特性相似。本文将在第5部分代码实现模块,讲解如何让Android应用支持客户端证书验证的方式。

(4) Android上TLS版本兼容问题

之前在接口联调的过程中,测试那边反馈过一个问题是在Android 4.4以下的系统出现HTTPS请求不成功而在4.4以上的系统上却正常的问题。相应的错误如下:

03-09 09:21:38.427: W/System.err(2496): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb7fa0620: Failure in SSL library, usually a protocol error 

03-09 09:21:38.427: W/System.err(2496): error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0xa90e6990:0x00000000)

按照官方文档的描述,Android系统对SSL协议的版本支持如下:

分析 HTTPS 原理以及在 Android 中的使用

也就是说,按官方的文档显示,在API 16+以上,TLS1.1和TLS1.2是默认开启的。但是实际上在API 20+以上才默认开启,4.4以下的版本是无法使用TLS1.1和TLS 1.2的,这也是Android系统的一个bug。

参照stackoverflow上的一些方式,比较好的一种解决方案如下:

SSLSocketFactory noSSLv3Factory; 
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { 
    noSSLv3Factory = new TLSSocketFactory(mSSLContext.getSSLSocket().getSocketFactory()); 
} else { 
    noSSLv3Factory = mSSLContext.getSSLSocket().getSocketFactory(); 
}

对于4.4以下的系统,使用自定义的TLSSocketFactory,开启对TLS1.1和TLS1.2的支持,核心代码:

public class TLSSocketFactory extends SSLSocketFactory { 

    private SSLSocketFactory internalSSLSocketFactory; 

    public TLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException { 
        SSLContext context = SSLContext.getInstance("TLS"); 
        context.init(null, null, null); 
        internalSSLSocketFactory = context.getSocketFactory(); 
    } 

    public TLSSocketFactory(SSLSocketFactory delegate) throws KeyManagementException, NoSuchAlgorithmException { 
        internalSSLSocketFactory = delegate; 
    } 

    ...... 

    @Override 
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { 
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort)); 
    } 

    // 开启对TLS1.1和TLS1.2的支持 
    private Socket enableTLSOnSocket(Socket socket) { 
        if(socket != null && (socket instanceof SSLSocket)) { 
            ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2"}); 
        } 
        return socket; 
    } 
}
5.代码实现

本部分主要基于第四部分提出的Android应用中使用HTTPS遇到的一些常见的问题,给出一个比较系统的解决方案。

(1) 整体结构

不管是使用自签名证书,还是采取客户端身份验证,核心都是创建一个自己的KeyStore,然后使用这个KeyStore创建一个自定义的SSLContext。整体类图如下:

分析 HTTPS 原理以及在 Android 中的使用

类图中的MySSLContext可以应用在HttpURLConnection的方式与服务端连接的过程中:

if (JarConfig.__self_signed_https) { 
    SSLContextByTrustAll mSSLContextByTrustAll = new SSLContextByTrustAll(); 
    MySSLContext mSSLContext = new MySSLContext(mSSLContextByTrustAll); 
   SSLSocketFactory noSSLv3Factory; 
   if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { 
        noSSLv3Factory = new TLSSocketFactory(mSSLContext.getSSLSocket().getSocketFactory()); 
    } else { 
        noSSLv3Factory = mSSLContext.getSSLSocket().getSocketFactory(); 
    } 

    httpsURLConnection.setSSLSocketFactory(noSSLv3Factory); 
    httpsURLConnection.setHostnameVerifier(MY_DOMAIN_VERIFY); 
}else { 
    httpsURLConnection.setSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault()); 
    httpsURLConnection.setHostnameVerifier(DO_NOT_VERIFY); 
}

核心是通过httpsURLConnection.setSSLSocketFactory使用自定义的校验逻辑。整体设计上使用策略模式决定采用哪种验证机制:

  • makeContextWithCilentAndServer 单向验证方式(自定义信任的证书集合)
  • makeContextWithServer 双向验证方式(自定义信任的证书集合,并使用客户端证书)
  • makeContextToTrustAll (信任所有的CA证书,不安全,仅供测试阶段使用)

(2) 单向验证并自定义信任的证书集合

在App中,把服务端证书放到资源文件下(通常是asset目录下,因为证书对于每一个用户来说都是相同的,并且也不会经常发生改变),但是也可以放在设备的外部存储上。

public class SSLContextWithServer implements GetSSLSocket { 

    // 在这里进行服务器正式的名称的配置 
    private String[] serverCertificateNames = {"serverCertificateNames1" ,"serverCertificateNames2"}; 

    @Override 
    public SSLContext getSSLSocket() { 
        String[] caCertString = new String[serverCertificateNames.length]; 
        for(int i = 0 ; i < serverCertificateNames.length ; i++) { 
            try { 
                caCertString[i] = readCaCert(serverCertificateNames[i]); 
            } catch(Exception e) { 

            } 
        } 
        SSLContext mSSLContext = null; 
        try { 
            mSSLContext = SSLContextFactory.getInstance().makeContextWithServer(caCertString); 
        } catch(Exception e) { 

        } 
        return mSSLContext; 
    }

serverCertificateNames中定义了App所信任的证书名称(这些证书文件必须要放在指定的文件路径下,并其要保证名称相同),而后就可以加载服务端证书链到keystore,通过获取到的可信任并带有服务端证书的keystore,就可以用它来初始化自定义的SSLContext了:

@Override 
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
        try { 
            originalX509TrustManager.checkServerTrusted(chain, authType); 
        } catch(CertificateException originalException) { 
            try { 
                X509Certificate[] reorderedChain = reorderCertificateChain(chain); 
                CertPathValidator validator = CertPathValidator.getInstance("PKIX"); 
                CertificateFactory factory = CertificateFactory.getInstance("X509"); 
                CertPath certPath = factory.generateCertPath(Arrays.asList(reorderedChain)); 
                PKIXParameters params = new PKIXParameters(trustStore); 
                params.setRevocationEnabled(false); 
                validator.validate(certPath, params); 
            } catch(Exception ex) { 
                throw originalException; 
            } 
        } 
    }

(3) 跳过证书校验过程

和上面的过程类似,只不过这里提供的TrustManager不需要提供信任的证书集合,默认接受任意客户端证书即可:

public class AcceptAllTrustManager implements X509TrustManager { 

    @Override 
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
        //do nothing,接受任意客户端证书 
    } 

    @Override 
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
        //do nothing,接受任意服务端证书 
    } 

    @Override 
    public X509Certificate[] getAcceptedIssuers() { 
        return null; 
    }

而后构造相应的SSLContext:

public SSLContext makeContextToTrustAll() throws Exception { 
        AcceptAllTrustManager tm = new AcceptAllTrustManager(); 
        SSLContext sslContext = SSLContext.getInstance("TLS"); 
        sslContext.init(null, new TrustManager[] { tm }, null); 

        return sslContext; 
}

Das obige ist der detaillierte Inhalt vonAnalysieren Sie die Prinzipien von HTTPS und seine Verwendung in Android. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:linuxprobe.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen