Javax.net.ssl.SSLHandshakeException: java.lang.IllegalArgumentException: недопустимый ввод в toASCII: ip_nbae7bac35.kodrive.xyz

Есть ли обходной путь для этого исключения? глядя на этот проблема на github, похоже, что это может быть ошибка Android, что-то о имени хоста, имеющем символ подчеркивания или что-то в этом роде.

Это трассировка стека:

javax.net.ssl.SSLHandshakeException: java.lang.IllegalArgumentException: Invalid input to toASCII: ip_nbae7bac35.kodrive.xyz
        at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:219)
        at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:318)
        at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:282)
        at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:167)
        at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
        at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
        at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
        at okhttp3.RealCall.execute(RealCall.java:77)
8
0
2 800
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Ваша проблема в том, что вы не можете преобразовать строку в ASCII, используя toASCII, который содержит _. Нет другого выхода, кроме как связаться с владельцем домена и попросить его удалить _. Вот почему у вас IllegalArgumentException, строка была "недопустимой".

Получение того же символа подчеркивания в имени хоста. Есть ли способ обойти то же самое. URL-адрес работает, это запрос почтальона, но почему не в запросе на модернизацию

Pragya Singla 18.12.2018 11:35
import java.security.SecureRandom;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * 忽略https证书验证
 */

public class SSLSocketClient {
    //获取这个SSLSocketFactory
    public static SSLSocketFactory getSSLSocketFactory() {
        try {
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, getTrustManager(), new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //获取TrustManager
    private static TrustManager[] getTrustManager() {
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) {
            }

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

    //获取HostnameVerifier
    public static HostnameVerifier getHostnameVerifier() {
        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String s, SSLSession sslSession) {
                return true;
            }
        };
        return hostnameVerifier;
    }
}
OkHttpClient.Builder builder = ...
builder.sslSocketFactory(SSLSocketClient.getSSLSocketFactory())
       .hostnameVerifier(SSLSocketClient.getHostnameVerifier())

Не могли бы вы добавить к своему ответу более подробную информацию? Чем он отличается от принятого ответа?

razdi 23.10.2019 08:22

Я не публиковал этот ответ, но в основном он принимает все имена хостов, которые я думаю. Я не реализовал это, так как не думаю, что Google позволяет это в Play Store, по крайней мере, я слышал об этом.

casolorz 23.10.2019 18:48

Это всего лишь пример. Вы должны добавить свой собственный сертификат. Если вы добавите поддержку ssh, ошибки _ не будет. Итак, нет исключения IllegalArgumentException

ikakaxi 24.10.2019 09:04

Я решил эту проблему, напишу код, который будет принимать все сертификаты ssl, надеюсь, вы не будете заниматься этим часами, как я. Когда увидел одобренный комментарий, то подумал, что он неразрешим, но решил :)

Код Котлина:

import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.io.IOException
import java.security.SecureRandom
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

class ExampleClient {
    companion object{
        private fun httpClient(accessToken: String): OkHttpClient.Builder? {
            return try { // Create a trust manager that does not validate certificate chains
                val trustAllCerts =
                    arrayOf<TrustManager>(
                        object : X509TrustManager {
                            @Throws(CertificateException::class)
                            override fun checkClientTrusted(
                                chain: Array<X509Certificate>,
                                authType: String
                            ) {
                            }

                            @Throws(CertificateException::class)
                            override fun checkServerTrusted(
                                chain: Array<X509Certificate>,
                                authType: String
                            ) {
                            }

                            override fun getAcceptedIssuers(): Array<X509Certificate> {
                                return arrayOf()
                            }
                        }
                    )
                // Install the all-trusting trust manager
                val sslContext =
                    SSLContext.getInstance("SSL")
                sslContext.init(null, trustAllCerts, SecureRandom())
                // Create an ssl socket factory with our all-trusting manager
                val sslSocketFactory = sslContext.socketFactory
                val builder = OkHttpClient.Builder()
                builder.addInterceptor(object : Interceptor {
                    @Throws(IOException::class)
                    override fun intercept(chain: Interceptor.Chain): Response {
                        val original = chain.request()
                        // Request customization: add request headers
                        val requestBuilder = original.newBuilder()
                            .addHeader("Authorization", accessToken)
                        val request = requestBuilder.build()
                        return chain.proceed(request)
                    }
                })
                builder.sslSocketFactory(
                    sslSocketFactory,
                    (trustAllCerts[0] as X509TrustManager)
                )
                builder.hostnameVerifier(HostnameVerifier { hostname, session -> true })
                builder
            } catch (e: Exception) {
                throw RuntimeException(e)
            }
        }
        fun getClient(accessToken: String):Retrofit{
            return Retrofit.Builder()
                .baseUrl("https://sub_domain.base-url.com")
                .addConverterFactory(GsonConverterFactory.create())
                .client(httpClient(accessToken)!!.build())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
        }
    }

}

Код Java:

import android.content.ContextWrapper;
import com.pixplicity.easyprefs.library.Prefs;
import java.io.IOException;
import java.security.cert.CertificateException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class Client {
    public static String deviceid;
    private static Retrofit retrofit;
    public static String BASE_URL = "https://base_url.com/api/";
    public static OkHttpClient.Builder getUnsafeOkHttpClient() {

        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // Create an ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Interceptor.Chain chain) throws IOException {
                    Request original = chain.request();

                    String token;
                    try {
                        token = Prefs.getString("token","Token not found");
                    }catch (Exception e){
                        token = LoginActivity.getToken();
                    }

                    // Request customization: add request headers
                    Request.Builder requestBuilder = original.newBuilder()
                            .header("deviceid", deviceid).addHeader("Authorization","Bearer " + token);


                    Request request = requestBuilder.build();
                    return chain.proceed(request);
                }
            });
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            return builder;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }



    public static Retrofit getClient(String device_id){

        deviceid = device_id;
        MyLog.log("DEVICE ID : "+deviceid);
        if (retrofit == null){
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(getUnsafeOkHttpClient().build())
                    .build();
            return retrofit;
        }
        return retrofit;
    }

}

Но разрешено ли это в Play Store? Я думал, что доверительные менеджеры, которые доверяют всем сертификатам, запрещены в Play Store.

casolorz 14.01.2020 17:36

Другие вопросы по теме