2017-01-09 4 views
2

У меня есть сертификат, выданный для IP-адреса (не общее имя), и я triyng для подключения к серверу с этим сертификатом.android retrofit Имя хоста не подтверждено

OkHttpClient.Builder builder = new OkHttpClient().newBuilder(); 
OkHttpClient okHttpClient = builder.build(); 
Gson gson = new GsonBuilder() 
       .setLenient() 
       .create(); 
retrofit = new Retrofit.Builder() 
       .baseUrl(url) 
       .client(okHttpClient) 
       .addConverterFactory(GsonConverterFactory.create(gson)) 
       .build(); 
ServerRouts service = retrofit.create(ServerRouts.class); 
Resp_json> call = service.login(param, user, pw); 

и я получил ошибку:

Hostname 11.8.222.333 not verified: 

, но когда я использую

builder.hostnameVerifier(new HostnameVerifier() { 
       @Override 
       public boolean verify(String hostname, SSLSession session) { 
        return true; 
       } 
      }); 

то все работает.

Как решить эту ошибку без отключения верификации имени хоста?

P.S. Мой сертификат, выданный для IP (11.8.222.333)

+0

проверьте его один раз, используя клиент отдыха, если он работает, чем вам нужно проверить проблему с модификацией! –

ответ

1

Я переопределил метод проверки (просто скопировал источники из DefaultHostnameVerifier.java), и теперь все работает. Я не знаю, почему это не сработало, но теперь все в порядке.

builder.hostnameVerifier(new HostnameVerifier() { 
      @Override 
      public boolean verify(String hostname, SSLSession session) { 

       Certificate[] certs; 
       try { 
        certs = session.getPeerCertificates(); 
       } catch (SSLException e) { 
        return false; 
       } 
       X509Certificate x509 = (X509Certificate) certs[0]; 
       // We can be case-insensitive when comparing the host we used to 
       // establish the socket to the hostname in the certificate. 
       String hostName = hostname.trim().toLowerCase(Locale.ENGLISH); 
       // Verify the first CN provided. Other CNs are ignored. Firefox, wget, 
       // curl, and Sun Java work this way. 
       String firstCn = getFirstCn(x509); 
       if (matches(hostName, firstCn)) { 
        return true; 
       } 
       for (String cn : getDNSSubjectAlts(x509)) { 
        if (matches(hostName, cn)) { 
         return true; 
        } 
       } 
       return false; 

      } 
     }); 


private String getFirstCn(X509Certificate cert) { 
     String subjectPrincipal = cert.getSubjectX500Principal().toString(); 
     for (String token : subjectPrincipal.split(",")) { 
      int x = token.indexOf("CN="); 
      if (x >= 0) { 
       return token.substring(x + 3); 
      } 
     } 
     return null; 
    } 
+0

Что такое метод getFirstCn (x509) здесь – Nainal

+0

Я отредактировал свой ответ. – Rainmaker

Смежные вопросы