Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javax.net.ssl.SSLHandshakeException:当禁用SSLv2和SSlv3(仅限TLS)(及更高版本)时,Android 5.0.0上的握手失败_Java_Android_Ssl_Https_Retrofit - Fatal编程技术网

javax.net.ssl.SSLHandshakeException:当禁用SSLv2和SSlv3(仅限TLS)(及更高版本)时,Android 5.0.0上的握手失败

javax.net.ssl.SSLHandshakeException:当禁用SSLv2和SSlv3(仅限TLS)(及更高版本)时,Android 5.0.0上的握手失败,java,android,ssl,https,retrofit,Java,Android,Ssl,Https,Retrofit,这是我的第一篇文章,我将尽我最大的努力让自己尽可能清楚(对不起我的英语) 这是我的问题,我正在使用改进:1.9.0和okhttp:2.7.5来执行API调用。一切都很好,直到我的服务器提供商禁用SLLv2和SSLv3导致安全问题(3月1日发现溺水故障) 现在,我检查了有关我的提供商的信息,他只允许使用密码TLSv1(TLS 1.0 TLS_RSA_with_3DES_EDE_CBC_SHA No FS) 这是我做的所有测试和结果: [更新问题已解决] 在我的第二个答案中找到解决这个问题的方法 更

这是我的第一篇文章,我将尽我最大的努力让自己尽可能清楚(对不起我的英语)

这是我的问题,我正在使用改进:1.9.0和okhttp:2.7.5来执行API调用。一切都很好,直到我的服务器提供商禁用SLLv2和SSLv3导致安全问题(3月1日发现溺水故障)

现在,我检查了有关我的提供商的信息,他只允许使用密码TLSv1(TLS 1.0 TLS_RSA_with_3DES_EDE_CBC_SHA No FS)

这是我做的所有测试和结果:

[更新问题已解决]

在我的第二个答案中找到解决这个问题的方法

更新 问题似乎来自于GoogleAPI版本。当我在API 18上测试时,一切都正常。当它在Android greather或等于5.0.0时失败

第一次测试 配置重述:

public class LoginRestClient
{
    private static final String BASE_URL = "";
    private LoginApiService apiService;

    public LoginRestClient()
    {
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'")
                .create();

        RestAdapter restAdapter = new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setEndpoint(ApiIntentService.getHostAddress())
                .setConverter(new GsonConverter(gson))
                .setClient(new OkClient(ApiIntentService.getConnectionHttpClient()))
                .build();

        apiService = restAdapter.create(LoginApiService.class);
    }

    public LoginApiService getApiService() {
        return apiService;
    }
}
  • 编译DK23版
  • buildToolsVersion'23.0.2'
  • 明斯克版本18
  • targetSdkVersion 21
  • 改装:1.9.0
  • okhttp:2.7.5
  • Android版本>5.0.0(但在每台设备上都是一样的…)
Rest客户端(登录客户端):

public class LoginRestClient
{
    private static final String BASE_URL = "";
    private LoginApiService apiService;

    public LoginRestClient()
    {
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'")
                .create();

        RestAdapter restAdapter = new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setEndpoint(ApiIntentService.getHostAddress())
                .setConverter(new GsonConverter(gson))
                .setClient(new OkClient(ApiIntentService.getConnectionHttpClient()))
                .build();

        apiService = restAdapter.create(LoginApiService.class);
    }

    public LoginApiService getApiService() {
        return apiService;
    }
}
函数创建客户端OkHttpClient getConnectionHttpClient()

导致自定义回调的公共无效失败(错误)

java.net.UnknownServiceException:找不到可接受的协议。isFallback=false,modes=[ConnectionSpec(密码套件=[TLS_RSA_WITH_3DES_EDE_CBC_SHA],TLS版本=[TLS_1_0],supportsTlsExtensions=true)],支持的协议=[SSLv3,TLSv1,TLSv1.1,TLSv1.2]

第二次测试 我制作了一个自定义SSLSocketFactory来禁用SSLv3并强制TLS:

/**
 * @author fkrauthan
 */
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();
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return internalSSLSocketFactory.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return internalSSLSocketFactory.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
    }

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

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

    private Socket enableTLSOnSocket(Socket socket) {
        if(socket != null && (socket instanceof SSLSocket)) {
            ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1"});
        }
        return socket;
    }
}
我是这样使用它的:

public static OkHttpClient getConnectionHttpClient()
    {
        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.setReadTimeout(60, TimeUnit.SECONDS);
        okHttpClient.setConnectTimeout(60, TimeUnit.SECONDS);

        try {
            TLSSocketFactory tlsSocketFactory = new TLSSocketFactory();
            HttpsURLConnection.setDefaultSSLSocketFactory(tlsSocketFactory);
            okHttpClient.setSslSocketFactory(tlsSocketFactory);
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

 return okHttpClient;
}
导致自定义回调的公共无效失败(错误)

javax.net.ssl.SSLProtocolException:ssl握手中止:ssl=0x7f87885280:ssl库失败,通常是协议错误 错误:14077410:SSL例程:SSL23\u GET\u SERVER\u HELLO:sslv3警报握手失败(外部/openssl/SSL/s23\u clnt.c:770 0x7f87c2fdf0:0x00000000)

如果有人能帮我,那就太酷了。我的所有应用程序都已关闭,从昨天早上开始,我一直在努力解决这个问题,以恢复我的服务。我正在一个接一个地脱发


提前感谢。

问题已解决:

public class LoginRestClient
{
    private static final String BASE_URL = "";
    private LoginApiService apiService;

    public LoginRestClient()
    {
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'")
                .create();

        RestAdapter restAdapter = new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setEndpoint(ApiIntentService.getHostAddress())
                .setConverter(new GsonConverter(gson))
                .setClient(new OkClient(ApiIntentService.getConnectionHttpClient()))
                .build();

        apiService = restAdapter.create(LoginApiService.class);
    }

    public LoginApiService getApiService() {
        return apiService;
    }
}
大家好,经过3天3夜的战斗,这里是最终的解决方案。 因此,感谢这里的解决方案:

这个图书馆:

它允许Android在SSLv2和SSlv3被禁用的情况下提供更好的方式来使用cypher和TLS

首先创建此类NoSSLv3SocketFactory.java,并通过创建如下构造函数将其与CypherUrl连接耦合

public NoSSLv3SocketFactory(URL sourceUrl) throws IOException {
        this.delegate = NetCipher.getHttpsURLConnection(sourceUrl).getDefaultSSLSocketFactory();
    }
NoSSLv3SocketFactory.java(完整代码)

然后,在我的例子中,当您创建RestAdapter时,只需这样做,不要忘记设置您的客户端

public class LoginRestClient
{
    private static final String BASE_URL = "";
    private LoginApiService apiService;

    public LoginRestClient()
    {
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'")
                .create();

        RestAdapter restAdapter = new RestAdapter.Builder()
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setEndpoint(ApiIntentService.getHostAddress())
                .setConverter(new GsonConverter(gson))
                .setClient(ApiIntentService.createClient(60, TimeUnit.SECONDS, 20, TimeUnit.SECONDS))
                .build();

        apiService = restAdapter.create(LoginApiService.class);
    }

    public LoginApiService getApiService() {
        return apiService;
    }
}
有了这个,它应该可以工作了。
我希望它对其他人有用。

我在这里找到了解决方案

您只需在Android应用程序类中放置以下代码。这就足够了。无需对改装设置进行任何更改。它救了我一天

public class MyApplication extends Application {
@Override
public void onCreate() {
    super.onCreate();
    try {
      // Google Play will install latest OpenSSL 
      ProviderInstaller.installIfNeeded(getApplicationContext());
      SSLContext sslContext;
      sslContext = SSLContext.getInstance("TLSv1.2");
      sslContext.init(null, null, null);
      sslContext.createSSLEngine();
    } catch (GooglePlayServicesRepairableException | GooglePlayServicesNotAvailableException
        | NoSuchAlgorithmException | KeyManagementException e) {
        e.printStackTrace();
        }
    }
}

希望这会有所帮助。谢谢。

如果您使用的是OkHttpClient use,请检查是否包含了https://而不是将http://发送到您的服务器

OkHttpClient.Builder client = new OkHttpClient.Builder();
client.connectionSpecs(Arrays.asList(ConnectionSpec.COMPATIBLE_TLS));

设置客户端时使用do client.build()。

这对我有效:此解决方案解决了我的问题:我找到了解决方案并回答了。嗨,kevzzz,你能帮我解决我的问题吗?一个非常类似的解决方案以前对我有效。我从这里取了下来:不知什么原因,它似乎不再起作用了。然而,Taz的解决方案似乎正在发挥作用。太好了,它帮助了我!你知道kevzzz的解决方案有什么不同吗?几个月前它对我有效,但现在不再有效了。Android框架有什么变化吗?无论如何,我很高兴找到了你的解决方案!这救了我,因为我已经找了好几天了,为什么有些手机无法连接,而我却无法使用
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.connectionSpecs(Arrays.asList(ConnectionSpec.COMPATIBLE_TLS));