2017-09-08 3 views
0

現在、ドメイン名を持たず、そのIPアドレスでしかアクセスできないサーバーに接続しようとしています。私はこれまでに図書館のボレーを使ってこれをやろうとしていましたが、研究の1日を過ごした後に、なぜsslの握手がうまくいかないのか分かりませんでした。Okhttp 3(アンドロイド):自己署名付きのsslでIPアドレスに接続

javax.net.ssl.SSLPeerUnverifiedException:検証されていないホスト名185.101.92.193:
証明書:SHA256/QMgPlAslWrBi1dd/P17AKxJCniO2RfHQ5MufVO5Xji4 =
DN:1.2.840.113549.1.9 Okhttpに切り替えた後、私は警告を受けました。 1 =#1619626c61636b6a61636b34323636323440676d61696c2e636f6d、CN = 185.101.92.193、O =インターネットWidgits Pty Ltdの、L =ベルリン、ST =ベルリン、C = DE
subjectAltNamesを:[]

今、この問題はすでにgithubの上で対処されてきました:https://github.com/square/okhttp/issues/1467

私は次のコードに問題が(一番下のHostnameVerifierを見て)「解決」している:

// loading CAs from an InputStream 
     try { 
      CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
      InputStream cert = context.getResources().openRawResource(R.raw.servercert); 
      Certificate ca; 
      try { 
       ca = cf.generateCertificate(cert); 
      } finally { 
       cert.close(); 
      } 

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

      // creating a TrustManager that trusts the CAs in our KeyStore 
      String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
      TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
      tmf.init(keyStore); 

      // creating an SSLSocketFactory that uses our TrustManager 
      SSLContext sslContext = SSLContext.getInstance("TLS"); 
      sslContext.init(null, tmf.getTrustManagers(), null); 
      client = new OkHttpClient.Builder().sslSocketFactory(sslContext.getSocketFactory()) 
        .hostnameVerifier(new HostnameVerifier() { 
         @Override 
         public boolean verify(String s, SSLSession sslSession) { 
          if(s.equals(myIPAddress)){ 
           return true; 
          }else{ 
           return false; 
          } 
         } 
        }) 
        .build(); 
     }catch (Exception e){ 
      e.printStackTrace(); 
     } 

は今、これはちょっと私には悪い習慣のように見え、私の実際の質問は次のとおりです。問題が発生する可能性がどのようなこのようなHostnameVerifier(セキュリティ上の問題)を実装することから、どのように私はこの問題をより洗練された方法で解決できますか?

+0

サーバーのドメイン名を取得できます。ドメイン名はかなり安いです。 – CommonsWare

+0

うん、あなたはポイントを持っています。しかし、誰かがなぜ私がここで何をしてはならないのか教えてもらうために、私はそれを学ぶために、私はまだ待っています。 – Doflaminhgo

答えて

2

ドメイン名とは関係ありません。唯一の問題は、アプリケーション(アンドロイド)がプライベート(自己署名入りの証明書)であるため証明書を確認できないことです。あなたのコードで行ったことは、SSLFactoryをオーバーライドして検証プロセスをバイパスしようとしているだけで、CAを使用する新しいものを作成しただけです。 下記のアンドロイドのドキュメントを確認してください。 https://developer.android.com/training/articles/security-ssl.html#CommonProblems

あなたは何かを続けることができます。または証明書を購入し、このコードをまったく必要としません。

関連する問題