1. ホーム
  2. java

[解決済み] OkHttpは自己署名SSL証明書の受理をサポートしていますか?

2023-05-12 20:43:59

質問

私は、自己署名SSL証明書を持つサーバーを持っている顧客のために働いています。

Retrofit + CustomClientでOkHttpクライアントをラップして使っています。

RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint(Config.BASE_URL + Config.API_VERSION)
    .setClient(new CustomClient(new OkClient(), context))
    .build();

OkHttpはデフォルトで自己署名SSL証明書サーバを呼び出すことをサポートしていますか?

ちなみに Retrofitはどのクライアントがデフォルトで使っているのでしょうか?私はOkHttpだと思っていたのですが、もう少し調べるとOkHttpの依存関係をインポートする必要があることに気づきました

解決方法は?

はい、解決しました。

Retrofitは、あなたのニーズに合わせて設定された、カスタムHTTPクライアントを設定することができます。

自己署名SSL証明書に関しては、以下の議論があります。 ここで . このリンクには、自己署名SSLをAndroidの DefaultHttpClient に自己署名SSLを追加し、このクライアントをRetrofitに読み込ませるためのコードサンプルが含まれています。

もしあなたが OkHttpClient が自己署名SSLを受け入れるために必要であれば、それをカスタム javax.net.ssl.SSLSocketFactory インスタンスを setSslSocketFactory(SSLSocketFactory sslSocketFactory) メソッドを介して

ソケットファクトリを取得する最も簡単な方法は、ソケットファクトリを javax.net.ssl.SSLContext で説明したように ここで .

OkHttpClientを設定するためのサンプルです。

OkHttpClient client = new OkHttpClient();
KeyStore keyStore = readKeyStore(); //your method to obtain KeyStore
SSLContext sslContext = SSLContext.getInstance("SSL");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "keystore_pass".toCharArray());
sslContext.init(keyManagerFactory.getKeyManagers(),trustManagerFactory.getTrustManagers(), new SecureRandom());
client.setSslSocketFactory(sslContext.getSocketFactory());


okhttp3のコードを更新(builderを使用)。

    OkHttpClient client = new OkHttpClient.Builder()
            .sslSocketFactory(sslContext.getSocketFactory())
            .build();


client の証明書を使用するように設定されています。 KeyStore . しかし、信頼できるのはあなたの KeyStore の中の証明書しか信用せず、それ以外のものは信用しません。たとえシステムがデフォルトで信用していたとしてもです。(自己署名証明書だけを KeyStore に自己署名証明書だけを記述し、HTTPS で Google のメインページに接続しようとすると、次のようになります。 SSLHandshakeException ).

を取得することができます。 KeyStore のインスタンスを取得できます。 ドキュメント :

KeyStore readKeyStore() {
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());

    // get user password and file input stream
    char[] password = getPassword();

    java.io.FileInputStream fis = null;
    try {
        fis = new java.io.FileInputStream("keyStoreName");
        ks.load(fis, password);
    } finally {
        if (fis != null) {
            fis.close();
        }
    }
    return ks;
}

アンドロイドの場合、このファイルを res/raw フォルダから取得し Context のインスタンスから

fis = context.getResources().openRawResource(R.raw.your_keystore_filename);

鍵ストアの作成方法については、いくつかの議論があります。たとえば ここで