webentwicklung-frage-antwort-db.com.de

So richten Sie in Retrofit eine https-Anforderung mit einem SSL-Zertifikat ein

Ich habe eine .p12-Zertifikatdatei und verwende den SSL Converter , um sie in eine .pem-Zertifikatdatei zu konvertieren. Dann verwende ich diese Pem-Zertifikatdatei in meinem Android-Code wie folgt:

OkHttpClient okHttpClient = new OkHttpClient();
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream instream = context.getResources().openRawResource(R.raw.pem_certificate);
            Certificate ca;
            ca = cf.generateCertificate(instream);
            KeyStore kStore = KeyStore.getInstance(KeyStore.getDefaultType());
            kStore.load(null, null);
            kStore.setCertificateEntry("ca", ca);
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(kStore);
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), null);
            okHttpClient.setSslSocketFactory(sslContext.getSocketFactory());
        } catch (CertificateException
                | KeyStoreException
                | NoSuchAlgorithmException
                | IOException
                | KeyManagementException e) {
            e.printStackTrace();
        }

        baseURL = endpoint;
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(baseURL)
                .setClient(new OkClient(okHttpClient))
                .build();

        service = restAdapter.create(DishService.class);

Dieser Code funktioniert jedoch nicht. Es wurde in der Zeile "ca = cf.generateCertificate (instream);" mit der CertificateException-Nachricht.

7
congtrungvnit

Vielleicht hast du ein Problem in R.raw.pem_certificate ...

1) Versuchen Sie, ein öffentliches Rohzertifikat mit openssl : Openssl s_client -connect {HOSTNAME}: {PORT} -showcertsabzurufen

(Details finden Sie hier: https://superuser.com/questions/97201/how-to-save-a-remote-server-ssl-certificate-locally-as-a-file )

2) So richten Sie Retrofit2 mit einem benutzerdefinierten SSL-Zertifikat ein https://adiyatmubarak.wordpress.com/tag/add-ssl-certificate-in-retrofit-2/

oder Retrofit1: https://number1.co.za/use-retrofit-self-signed-unknown-ssl-certificate-Android/

PS: Es funktioniert für mich, bitte konvertieren Sie keine PEM-Datei in BKS.

3
Maxim Firsoff

Versuchen Sie die Antwort unter dem Link, der für mich funktioniert hat

Nachrüstung 2.3.0

Selbstsigniertes SSL-Zertifikat nachrüsten

0
Gowsik K C
public class RetrofitBuilder {

private static Retrofit retrofit = null;
private static final String BASE_URL = BuildConfig.BASE_URL;
private static final String API_VERSION = BuildConfig.VERSION;

private static OkHttpClient.Builder httpClientBuilder = null;

public static Retrofit getInstance(Context context) {
    if (retrofit == null) {

        httpClientBuilder = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS);
        initHttpLogging();
        initSSL(context);

        Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl(BASE_URL + API_VERSION)
                .addConverterFactory(GsonConverterFactory.create())
                .client(httpClientBuilder.build());


        retrofit = builder.build();

    }
    return retrofit;
}


private static void initHttpLogging() {
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);
    if (BuildConfig.DEBUG) httpClientBuilder.addInterceptor(logging);
}

private static void initSSL(Context context) {

    SSLContext sslContext = null;
    try {
        sslContext = createCertificate(context.getResources().openRawResource(R.raw.cert));
    } catch (CertificateException | IOException | KeyStoreException | KeyManagementException | NoSuchAlgorithmException e) {
        e.printStackTrace();
    }

    if(sslContext!=null){
        httpClientBuilder.sslSocketFactory(sslContext.getSocketFactory(), systemDefaultTrustManager());
    }

}

private static SSLContext createCertificate(InputStream trustedCertificateIS) throws CertificateException, IOException, KeyStoreException, KeyManagementException, NoSuchAlgorithmException{

    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    Certificate ca;
    try {
        ca = cf.generateCertificate(trustedCertificateIS);
    } finally {
        trustedCertificateIS.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);
    return sslContext;

}

private static X509TrustManager systemDefaultTrustManager() {

    try {
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init((KeyStore) null);
        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
        if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
            throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
        }
        return (X509TrustManager) trustManagers[0];
    } catch (GeneralSecurityException e) {
        throw new AssertionError(); // The system has no TLS. Just give up.
    }

}

}

Nachdem ich viele Posts, Blogs und Gist gelesen hatte, fand ich endlich einen Weg. Das funktioniert für mich.

0
Jay