在改造库中禁用 SSL 证书签核

2022-09-01 21:35:54

我正在使用Android中的改造来连接服务器。

public class ApiClient {
    public static final String BASE_URL = "https://example.com/";
    private static Retrofit retrofit = null;

    public static Retrofit getClient() {
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

这是我的开发服务器,我想禁用证书检查。如何在此代码中实现?

错误:javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: 未找到证书路径的信任锚点。


答案 1

使用此类获取不安全的改造实例。我已将导入包括在内以避免混淆。

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.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import view.utils.AppConstants;

/**
 * Created by Hitesh.Sahu on 11/23/2016.
 */

public class NetworkHandler {

    public static Retrofit getRetrofit() {

        return new Retrofit.Builder()
                .baseUrl(AppConstants.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(getUnsafeOkHttpClient())
                .build();
    }


    private static OkHttpClient 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.sslSocketFactory(sslSocketFactory);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            OkHttpClient okHttpClient = builder.build();
            return okHttpClient;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

然后简单地使用改造,而无需像这样进行SSL检查

    private void postFeedbackOnServer() {

        MyApiEndpointInterface apiService =
                NetworkHandler.getRetrofit().create(MyApiEndpointInterface.class);

        Call<ResponseBE> call = apiService.submitFeedbackToServer(requestObject);

        Log.e(TAG ,  "Request is" + new Gson().toJson(requestObject).toString() );

        call.enqueue(new Callback<ResponseBE>() {
            @Override
            public void onResponse(Call<ResponseBE> call, Response<ResponseBE> response) {
                int statusCode = response.code();

                if (statusCode == HttpURLConnection.HTTP_OK) {

              ......

                } else {
                    Toast.makeText(FeedbackActivity.this, "Failed to submit Data" + statusCode, Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<ResponseBE> call, Throwable t) {

                // Log error here since request failed
                Toast.makeText(FeedbackActivity.this, "Failure" + t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();

            }
        });
    }

答案 2

自从Hitesh Sahu的答案发布以来,语法发生了一些变化。现在,您可以对某些方法使用 lambdas,删除一些 throw 子句和链生成器方法调用。

private static OkHttpClient createOkHttpClient() {
    try {
        final TrustManager[] trustAllCerts = new TrustManager[] {
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {}

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

                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new java.security.cert.X509Certificate[]{};
                    }
                }
        };
        final SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        return new OkHttpClient.Builder()
                .sslSocketFactory(sslContext.getSocketFactory())
                .hostnameVerifier((hostname, session) -> true)
                .build();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}