2017-10-26 9 views
0

Diese Frage kann ein Duplikat von How can I pin a certificate with Square OKHTTP? sein Aber da es nicht klar ist, frage ich noch einmal. Ich muss ein SSL-Zertifikat an meinen http-Client anhängen. Ich benutze Retrofit Version 2.2.0 und okHttp Version 3.6.0Zertifikat pinning mit okHttp

Ich habe ein Zertifikat in .crt Format. Derzeit mache ich das Zertifikat pinning as shown here. Aber ich weiß es nicht oder nicht. Im Anschluss an meinem Code

 static void pinCertificate(Context context, OkHttpClient.Builder builder) { 
      try { 
       CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
       InputStream cert = context.getResources().openRawResource(R.raw.certificate); 
       Certificate ca; 
       ca = cf.generateCertificate(cert); 

       // creating a KeyStore containing our trusted CAs 
       String keyStoreType = KeyStore.getDefaultType(); 
       KeyStore keyStore = KeyStore.getInstance(keyStoreType); 
       keyStore.load(null, null); 
       keyStore.setCertificateEntry("ca", ca); 


       String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
       TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
       tmf.init(keyStore); 


       SSLContext sslContext = SSLContext.getInstance("TLS"); 
       sslContext.init(null, tmf.getTrustManagers(), null); 
       builder.sslSocketFactory(sslContext.getSocketFactory()); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 

Ist es der richtige Weg, um ein .crt Zertifikat mit okHttp zu? Wie können wir testen, ob es den Handshake richtig macht? Wenn es falsch ist, kann jemand einen Beispielcode zeigen, um das Zertifikat richtig anzuheften? Ich sah einige Proben und Dokumente wie diese https://medium.com/@develodroid/android-ssl-pinning-using-okhttp-ca1239065616

aber es ist völlig anders als was ich implementiert habe. Nirgendwo haben sie eine crt Datei verwendet.

Wenn jemand eine bessere Erklärung über Certificate Pinning und wie es in okHttp getan werden kann, wäre es sehr hilfreich. Vielen Dank im Voraus !!

+1

Ihr Code ist für die Unterstützung eines selbstsignierten Zertifikats, das mehr als nur Pinning erfordert. Wenn Sie ein Standardzertifikat von einer Zertifizierungsstelle mit einem Zertifikat versehen möchten, ist der Medium-Post, zu dem Sie eine Verknüpfung herstellen, in Ordnung. – CommonsWare

+0

'crt' Datei bedeutet, dass es ein selbstsigniertes Zertifikat ist? – Jrd

+0

Nicht unbedingt. Fragen Sie, wer Ihre Website verwaltet, ob dies ein selbstsigniertes Zertifikat ist oder nicht. – CommonsWare

Antwort

1

Dies ist das Zertifikats-Pinning. Es ist der richtige Weg. Sie können es Fiedler oder charles mit Test von httpsZertifikat in Telefon installieren. Wenn die Anfrage nicht erfolgreich ist, funktioniert das Pinning einwandfrei. Testen Sie es, indem Sie auch das SSL-Pinning deaktivieren. In diesem Fall wird Antrag erfolgreich sein, und Sie werden in der Lage sein Anfrage + Daten in Fiedler, um zu sehen oder charles

Sie auch Public-Key-Pinning verwenden könnte, die

sha öffentlicher Schlüssel im Zertifikat Pin werde ich umgesetzt haben folgendes Weg

  InputStream cert = context.getResources().openRawResource(R.raw.certificate);    
      CertificateFactory cf=CertificateFactory.getInstance("X.509", "BC"); 
      InputStream caInput = new BufferedInputStream(cert); 
      X509Certificate ca = (X509Certificate) cf.generateCertificate(caInput); 
      caInput.close(); 
      KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 
      keyStore.load(null); 
      keyStore.setCertificateEntry(ca.getSubjectX500Principal().getName(), ca); 
      KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509"); 
      kmf.init(keyStore, null); 
      KeyManager[] keyManagers = kmf.getKeyManagers(); 
      TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
      tmf.init(keyStore); 
      SSLContext context1 = SSLContext.getInstance("TLS"); 
      context1.init(keyManagers, tmf.getTrustManagers(), null); 
      builder.sslSocketFactory(context1.getSocketFactory()); 
+0

_ ** Dies ist das Zertifikats-Pinning. Es ist der richtige Weg ** _ du meinst den Code, den ich eingefügt habe? – Jrd

+0

"Dies ist Zertifikat pinning" - die Entwickler von OKHttp sind anderer Meinung. [** Dies ** ist das Zertifikats-Pinning] (https://github.com/square/okhttp/wiki/HTTPS#certificate-pinning). Was Sie haben, ist [die vertrauenswürdigen Zertifikate der Plattform durch Ihre eigenen ersetzen] (https://github.com/square/okhttp/wiki/HTTPS#customizing-trusted-certificates). – CommonsWare

+0

@CommonsWare gibt es irgendein Problem dabei? Muss ich etwas ändern? – Jrd

0

Die Art, wie Sie tun, ist der richtige Weg. Ich habe das auch auf die gleiche Weise getan, wie Sie es umsetzen. Es ist gut, damit zu gehen. Happy Coding :)