自己署名証明書によるHTTPS接続の受け入れ


153

HttpClientlib を使用してHTTPS接続を確立しようとしていますが、問題は、証明書がAndroidの信頼できる証明書のセットにリストされているVerisignGlobalSIgnなどの承認された認証局(CA)によって署名されていないためです。私は得続けjavax.net.ssl.SSLException: Not trusted server certificateます。

すべての証明書を受け入れるだけのソリューションを見てきましたが、ユーザーに質問したい場合はどうすればよいですか?

ブラウザーと同様のダイアログを表示して、ユーザーに続行するかどうかを決定させたい。ブラウザと同じ証明書ストアを使用したいのですが。何か案は?


この受け入れられた解決策は、ME-のために働いstackoverflow.com/questions/2642777/...
ベンカテッシュ

回答:


171

最初に行う必要があるのは、検証のレベルを設定することです。そのようなレベルはそれほど多くありません:

  • ALLOW_ALL_HOSTNAME_VERIFIER
  • BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
  • STRICT_HOSTNAME_VERIFIER

メソッドsetHostnameVerifier()は新しいライブラリapacheでは廃止されていますが、Android SDKのバージョンでは正常です。そして、それをALLOW_ALL_HOSTNAME_VERIFIERメソッドファクトリで取得して設定しSSLSocketFactory.setHostnameVerifier()ます。

次に、プロトコルのファクトリをhttpsに設定する必要があります。これを行うには、SchemeRegistry.register()メソッドを呼び出すだけです。

次に、DefaultHttpClientwith を作成する必要がありますSingleClientConnManager。また、以下のコードでは、デフォルトでALLOW_ALL_HOSTNAME_VERIFIERメソッドによってフラグ()も使用されることがわかりますHttpsURLConnection.setDefaultHostnameVerifier()

以下のコードは私にとってはうまくいきます:

HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

DefaultHttpClient client = new DefaultHttpClient();

SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());

// Set verifier     
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

// Example send http request
final String url = "https://encrypted.google.com/";
HttpPost httpPost = new HttpPost(url);
HttpResponse response = httpClient.execute(httpPost);

6
残念ながら、このコードを機能させることはできませんが、「信頼されていないサーバー証明書」をまだ取得しています。機能させるために設定する必要がある追加の権限はありますか?
ジュリー、2011

1
このコードはすべての証明書を受け入れるだけではありませんか?それを受け入れるにはポップアップが必要です。
モーテン

3
私が使用しているorg.apache.http.conn.ssl.SSLSocketFactory私が使用したくない理由javax.net.ssl.HttpsURLConnection
誰かどこか

9
このコードが証明書の検証を完全に無効にするよりも優れていることを説明できますか?私はandroidのssl APIに精通していませんが、一見するとアクティブな攻撃者に対してこれは完全に安全ではないようです。
CodesInChaos

3
SingleClientConnManagerの代わりにThreadSafeClientConnManagerを使用することをお勧めします
ファーム

124

Androidプラットフォームによって信頼されていると見なされない認証局からの安全な接続を実現するには、次の主な手順が必要です。

多くのユーザーからの要望に応じて、私はここの私のブログ記事から最も重要な部分をミラーリングしました:

  1. 必要なすべての証明書(ルートおよび中間CA)を取得します。
  2. keytoolとBouncyCastleプロバイダーを使用してキーストアを作成し、証明書をインポートします
  3. Androidアプリにキーストアをロードし、セキュリティで保護された接続に使用しますjava.net.ssl.HttpsURLConnection(標準の代わりにApache HttpClientを使用することをお勧めします(理解しやすく、パフォーマンスが高い))

証明書をつかむ

エンドポイント証明書からルートCAまでのチェーンを構築するすべての証明書を取得する必要があります。つまり、中間CA証明書(存在する場合)とルートCA証明書があります。エンドポイント証明書を取得する必要はありません。

キーストアを作成する

BouncyCastleプロバイダーをダウンロードし、既知の場所に保存します。また、keytoolコマンド(通常はJREインストールのbinフォルダーの下にあります)を起動できることを確認します。

次に、取得した証明書(エンドポイント証明書はインポートしないでください)をBouncyCastle形式のキーストアにインポートします。

テストはしませんでしたが、証明書をインポートする順序は重要だと思います。つまり、最下位の中間CA証明書を最初にインポートしてから、ルートCA証明書までインポートします。

次のコマンドを使用すると、パスワードmysecretを持つ新しいキーストア(存在しない場合)が作成され、中間CA証明書がインポートされます。また、BouncyCastleプロバイダーも定義しました。このプロバイダーは、私のファイルシステムとキーストア形式にあります。チェーン内の証明書ごとにこのコマンドを実行します。

keytool -importcert -v -trustcacerts -file "path_to_cert/interm_ca.cer" -alias IntermediateCA -keystore "res/raw/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret

証明書がキ​​ーストアに正しくインポートされたかどうかを確認します。

keytool -list -keystore "res/raw/mykeystore.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "path_to_bouncycastle/bcprov-jdk16-145.jar" -storetype BKS -storepass mysecret

チェーン全体を出力する必要があります:

RootCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 24:77:D9:A8:91:D1:3B:FA:88:2D:C2:FF:F8:CD:33:93
IntermediateCA, 22.10.2010, trustedCertEntry, Thumbprint (MD5): 98:0F:C3:F8:39:F7:D8:05:07:02:0D:E3:14:5B:29:43

これで、キーストアをAndroidアプリのrawリソースとしてコピーできます。 res/raw/

アプリでキーストアを使用する

まず、HTTPS接続にキーストアを使用するカスタムApache HttpClientを作成する必要があります。

import org.apache.http.*

public class MyHttpClient extends DefaultHttpClient {

    final Context context;

    public MyHttpClient(Context context) {
        this.context = context;
    }

    @Override
    protected ClientConnectionManager createClientConnectionManager() {
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        // Register for port 443 our SSLSocketFactory with our keystore
        // to the ConnectionManager
        registry.register(new Scheme("https", newSslSocketFactory(), 443));
        return new SingleClientConnManager(getParams(), registry);
    }

    private SSLSocketFactory newSslSocketFactory() {
        try {
            // Get an instance of the Bouncy Castle KeyStore format
            KeyStore trusted = KeyStore.getInstance("BKS");
            // Get the raw resource, which contains the keystore with
            // your trusted certificates (root and any intermediate certs)
            InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
            try {
                // Initialize the keystore with the provided trusted certificates
                // Also provide the password of the keystore
                trusted.load(in, "mysecret".toCharArray());
            } finally {
                in.close();
            }
            // Pass the keystore to the SSLSocketFactory. The factory is responsible
            // for the verification of the server certificate.
            SSLSocketFactory sf = new SSLSocketFactory(trusted);
            // Hostname verification from certificate
            // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
            sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
            return sf;
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

カスタムHttpClientを作成しました。これで安全な接続に使用できます。たとえば、RESTリソースに対してGET呼び出しを行う場合:

// Instantiate the custom HttpClient
DefaultHttpClient client = new MyHttpClient(getApplicationContext());
HttpGet get = new HttpGet("https://www.mydomain.ch/rest/contacts/23");
// Execute the GET call and obtain the response
HttpResponse getResponse = client.execute(get);
HttpEntity responseEntity = getResponse.getEntity();

それでおしまい ;)


8
これは、アプリケーションを出荷する前に証明書を取得する場合にのみ役立ちます。ユーザーが自分の証明書を受け入れるのに実際には役立ちません。アプリケーション用
ファジー

こんにちはすべて、上記の実装のためのトラストストアを使用したキーストアの検証プロセスを誰かに教えてもらえますか?事前に感謝..
andriod_testing

これは正常に機能しましたが、サーバーで証明書のキーを再生成すると問題が発生します。サーバー上の証明書を更新するたびに、クライアント側のストアも更新する必要があるのは奇妙に思われます。より良い方法がなければなりません:|
bpn

Gr8の回答、SingleClientConnManagerの代わりにThreadSafeClientConnManagerを使用することをお勧めします
ファーム

への/res/raw/mykeystore.bks参照を解決できませんが、を追加しました。これを解決するには?
uniruddh 14

16

サーバー上にデバイス上にないカスタム/自己署名証明書がある場合、以下のクラスを使用してそれをロードし、Androidのクライアント側で使用できます。

証明書*.crtファイルを/res/rawから入手できるように配置しますR.raw.*

以下のクラスを使用して、HTTPClientまたはHttpsURLConnectionその証明書を使用するソケットファクトリを取得します。

package com.example.customssl;

import android.content.Context;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;

public class CustomCAHttpsProvider {

    /**
     * Creates a {@link org.apache.http.client.HttpClient} which is configured to work with a custom authority
     * certificate.
     *
     * @param context       Application Context
     * @param certRawResId  R.raw.id of certificate file (*.crt). Should be stored in /res/raw.
     * @param allowAllHosts If true then client will not check server against host names of certificate.
     * @return Http Client.
     * @throws Exception If there is an error initializing the client.
     */
    public static HttpClient getHttpClient(Context context, int certRawResId, boolean allowAllHosts) throws Exception {


        // build key store with ca certificate
        KeyStore keyStore = buildKeyStore(context, certRawResId);

        // init ssl socket factory with key store
        SSLSocketFactory sslSocketFactory = new SSLSocketFactory(keyStore);

        // skip hostname security check if specified
        if (allowAllHosts) {
            sslSocketFactory.setHostnameVerifier(new AllowAllHostnameVerifier());
        }

        // basic http params for client
        HttpParams params = new BasicHttpParams();

        // normal scheme registry with our ssl socket factory for "https"
        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));

        // create connection manager
        ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);

        // create http client
        return new DefaultHttpClient(cm, params);
    }

    /**
     * Creates a {@link javax.net.ssl.HttpsURLConnection} which is configured to work with a custom authority
     * certificate.
     *
     * @param urlString     remote url string.
     * @param context       Application Context
     * @param certRawResId  R.raw.id of certificate file (*.crt). Should be stored in /res/raw.
     * @param allowAllHosts If true then client will not check server against host names of certificate.
     * @return Http url connection.
     * @throws Exception If there is an error initializing the connection.
     */
    public static HttpsURLConnection getHttpsUrlConnection(String urlString, Context context, int certRawResId,
                                                           boolean allowAllHosts) throws Exception {

        // build key store with ca certificate
        KeyStore keyStore = buildKeyStore(context, certRawResId);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        // Create an SSLContext that uses our TrustManager
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);

        // Create a connection from url
        URL url = new URL(urlString);
        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());

        // skip hostname security check if specified
        if (allowAllHosts) {
            urlConnection.setHostnameVerifier(new AllowAllHostnameVerifier());
        }

        return urlConnection;
    }

    private static KeyStore buildKeyStore(Context context, int certRawResId) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
        // init a default key store
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);

        // read and add certificate authority
        Certificate cert = readCert(context, certRawResId);
        keyStore.setCertificateEntry("ca", cert);

        return keyStore;
    }

    private static Certificate readCert(Context context, int certResourceId) throws CertificateException, IOException {

        // read certificate resource
        InputStream caInput = context.getResources().openRawResource(certResourceId);

        Certificate ca;
        try {
            // generate a certificate
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            ca = cf.generateCertificate(caInput);
        } finally {
            caInput.close();
        }

        return ca;
    }

}

キーポイント:

  1. Certificateオブジェクトは.crtファイルから生成されます。
  2. デフォルトKeyStoreが作成されます。
  3. keyStore.setCertificateEntry("ca", cert)証明書を別名「ca」の下の鍵ストアに追加しています。コードを変更して、証明書を追加します(中間CAなど)。
  4. 主な目的はSSLSocketFactoryHTTPClientまたはで使用できるを生成することHttpsURLConnectionです。
  5. SSLSocketFactory たとえば、ホスト名検証などをスキップするようにさらに構成できます。

詳細情報:http : //developer.android.com/training/articles/security-ssl.html


.crtファイルはどこで入手できますか?サーバーからダウンロードしますか?
zionpi

@zionpi証明書ファイルは、接続しているTLS対応サーバーで使用されるものと同じになります。
SD

ありがとう!これはとても簡単でした!
kapil thadani 2015年

@SD .crtの代わりに.P12ファイルを使用するにはどうすればよいですか?
Rakesh R Nair

私は、あなたは、ヘルプ似た疑いの冷たい喜ばれているstackoverflow.com/questions/57389622/...
StezPet

8

AndroidアプリをHTTPSを使用してRESTfulサービスに接続しようとしていらいらしました。また、証明書のチェックを完全に無効にすることを提案するすべての回答に少し悩まされました。もしそうなら、httpsのポイントは何ですか?

しばらくこのトピックについてググった後、ついに外部のjarが不要なこのソリューションを見つけました。AndroidAPIだけです。2014年7月に投稿したAndrew Smithに感謝

 /**
 * Set up a connection to myservice.domain using HTTPS. An entire function
 * is needed to do this because myservice.domain has a self-signed certificate.
 * 
 * The caller of the function would do something like:
 * HttpsURLConnection urlConnection = setUpHttpsConnection("https://littlesvr.ca");
 * InputStream in = urlConnection.getInputStream();
 * And read from that "in" as usual in Java
 * 
 * Based on code from:
 * https://developer.android.com/training/articles/security-ssl.html#SelfSigned
 */
public static HttpsURLConnection setUpHttpsConnection(String urlString)
{
    try
    {
        // Load CAs from an InputStream
        // (could be from a resource or ByteArrayInputStream or ...)
        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        // My CRT file that I put in the assets folder
        // I got this file by following these steps:
        // * Go to https://littlesvr.ca using Firefox
        // * Click the padlock/More/Security/View Certificate/Details/Export
        // * Saved the file as littlesvr.crt (type X.509 Certificate (PEM))
        // The MainActivity.context is declared as:
        // public static Context context;
        // And initialized in MainActivity.onCreate() as:
        // MainActivity.context = getApplicationContext();
        InputStream caInput = new BufferedInputStream(MainActivity.context.getAssets().open("littlesvr.crt"));
        Certificate ca = cf.generateCertificate(caInput);
        System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());

        // Create a KeyStore containing our trusted CAs
        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        // Create a TrustManager that trusts the CAs in our KeyStore
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        // Create an SSLContext that uses our TrustManager
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);

        // Tell the URLConnection to use a SocketFactory from our SSLContext
        URL url = new URL(urlString);
        HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
        urlConnection.setSSLSocketFactory(context.getSocketFactory());

        return urlConnection;
    }
    catch (Exception ex)
    {
        Log.e(TAG, "Failed to establish SSL connection to server: " + ex.toString());
        return null;
    }
}

それは私のモックアップアプリでうまく機能しました。


X509Certificate Javaとjavaxのどちらをインポートする必要がありますか?
Siddharth

インポートしたimport java.security.cert.X509Certificate;
GonzaloFernández16年

これはありがとう.itは本当に機能的でシンプルです
Anuradhe Dilshan

6

一番上の答えはうまくいきませんでした。調査の結果、「Android Developer」で必要な情報を見つけました:https : //developer.android.com/training/articles/security-ssl.html#SelfSigned

X509TrustManagerの空の実装を作成すると、トリックが行われました。

private static class MyTrustManager implements X509TrustManager
{

    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType)
         throws CertificateException
    {
    }

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

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

}

...

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
try
{
    // Create an SSLContext that uses our TrustManager
    SSLContext context = SSLContext.getInstance("TLS");
    TrustManager[] tmlist = {new MyTrustManager()};
    context.init(null, tmlist, null);
    conn.setSSLSocketFactory(context.getSocketFactory());
}
catch (NoSuchAlgorithmException e)
{
    throw new IOException(e);
} catch (KeyManagementException e)
{
    throw new IOException(e);
}
conn.setRequestMethod("GET");
int rcode = conn.getResponseCode();

TustManagerのこの空の実装は単なる例であり、本番環境で使用すると重大なセキュリティ上の脅威が発生することに注意してください。


1
ただfyi-当時このような状況だった場合はidk ですが、彼らは現在このアプローチを強く妨げているようです(注を参照)
Saik Caskey

6

HTTP / HTTPS接続にはAndroid Volleyを使用することをお勧めしますHttpClient。これは非推奨であるためです。だから、あなたは正しい選択を知っています:)。

また、SSL証明書を無効にしないでください(絶対に!!!)。

SSL証明書を核にすることは、セキュリティを促進するSSLの目的に完全に反します。来るすべてのSSL証明書を爆撃することを計画している場合、SSLを使用する意味はありません。より良いソリューションは、SSLを使用しないこと、またはTrustManagerHTTP / HTTPS接続にAndroid Volleyを使用してアプリでカスタムを作成することです。

これは、サーバー側の自己署名証明書を使用してHTTPS接続を実行し、アプリで受け入れられる、基本的なLoginAppで作成した要点です。

サーバーで設定するための自己署名SSL証明書を作成し、アプリで証明書を使用するために役立つ、もう1つの要点もあります。非常に重要:上記のスクリプトで生成された.crtファイルをAndroidプロジェクトの「raw」ディレクトリにコピーする必要があります。


こんにちは、イワンです。SSL証明書を扱ったことはありません。少し詳しく説明しますか。どうすれば.crtファイルを取得できますか?
jlively 2017年

こんにちは!そうですか。はい、もちろん。しかし、最初に、上で述べた2番目の要点を見てください。このGistに2つのファイルを配置しました。1つはスクリプトで使用されるファイルで、もう1つはスクリプト自体で、ファイルを読み取るために「openssl」バイナリを使用し、SSL証明書を含むファイルを構築します( .crt)。全体を理解できたかどうか教えてください。よろしく:)
ivanleoncz

うーんはい、これら2つの要点を確認しましたが、どのように使用するのか本当に理解できません。
jlively 2017

4

この問題を回避するためにキーストアに証明書を追加する方法は次のとおりです。HTTPS経由のHttpClientを使用してすべての証明書を信頼する

質問のようにユーザーにプロンプ​​トを表示することはありませんが、ユーザーが「信頼されていないサーバー証明書」エラーに遭遇する可能性は低くなります。


テスト目的でのみ、このトリックを使用してアプリをPlayストアに公開することはできません。拒否されるためです
ariel

3

SSL証明書を作成する最も簡単な方法

Firefoxを開く(Chromeでも可能だと思いますが、FFを使用すると簡単です)

自己署名SSL証明書を使用して開発サイトにアクセスします。

証明書をクリックします(サイト名の横)

「詳細」をクリックします

「証明書の表示」をクリックします

「詳細」をクリック

「エクスポート...」をクリックします

「X.509 Certificate whith chain(PEM)」を選択し、保存するフォルダーと名前を選択して、「保存」をクリックします

コマンドラインで、pemファイルをダウンロードしたディレクトリに移動し、「openssl x509 -inform PEM -outform DM -in .pem -out .crt」を実行します。

.crtファイルをAndroidデバイス内の/ sdcardフォルダーのルートにコピーします。Androidデバイス内で、[設定]> [セキュリティ]> [ストレージからインストール]をクリックします。

証明書が検出され、デバイスに追加できるようになります。開発サイトを参照します。

初めてセキュリティ例外の確認を求めます。それで全部です。

証明書は、Androidにインストールされているすべてのブラウザー(ブラウザー、Chrome、Opera、Dolphin ...)で動作するはずです。

別のドメインから静的ファイルを提供している場合(すべてはページスピードの愚痴です)、そのドメインの証明書も追加する必要があることに注意してください。


2

Androidの特定の証明書を信頼するために、ssl-utils-androidという小さなライブラリを作成しました。

アセットディレクトリからファイル名を指定するだけで、任意の証明書をロードできます。

使用法:

OkHttpClient client = new OkHttpClient();
SSLContext sslContext = SslUtils.getSslContextForCertificateFile(context, "BPClass2RootCA-sha2.cer");
client.setSslSocketFactory(sslContext.getSocketFactory());

1

これらの修正は、SDK 16、リリース4.1.2をターゲットとする開発プラットフォームでは機能しなかったため、回避策を見つけました。

私のアプリは「http://www.example.com/page.php?data=somedata」を使用してサーバーにデータを保存します

最近、page.phpが「https://www.secure-example.com/page.php」に移動され、「javax.net.ssl.SSLException:信頼されていないサーバー証明書」が表示され続けます。

このガイドから始めて、単一ページのみのすべての証明書を受け入れる代わりに、「http://www.example.com/page.php」で公開された独自のpage.phpを作成する問題を解決しました

<?php

caronte ("https://www.secure-example.com/page.php");

function caronte($url) {
    // build curl request
    $ch = curl_init();
    foreach ($_POST as $a => $b) {
        $post[htmlentities($a)]=htmlentities($b);
    }
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($post));

    // receive server response ...
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $server_output = curl_exec ($ch);
    curl_close ($ch);

    echo $server_output;
}

?>

1

2020年1月19日、自己署名証明書の問題修正:

ビデオ、画像、自己署名証明書のWebサービスの呼び出し、またはセキュリティで保護されていないURLへの接続を再生するには、アクションを実行する前にこのメソッドを呼び出すだけで、証明書の問題に関する問題が修正されます。

KOTLINコード

  private fun disableSSLCertificateChecking() {
        val hostnameVerifier = object: HostnameVerifier {
            override fun verify(s:String, sslSession: SSLSession):Boolean {
                return true
            }
        }
        val trustAllCerts = arrayOf<TrustManager>(object: X509TrustManager {
            override fun getAcceptedIssuers(): Array<X509Certificate> {
                TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
            }

            //val acceptedIssuers:Array<X509Certificate> = null
            @Throws(CertificateException::class)
            override fun checkClientTrusted(arg0:Array<X509Certificate>, arg1:String) {// Not implemented
            }
            @Throws(CertificateException::class)
            override fun checkServerTrusted(arg0:Array<X509Certificate>, arg1:String) {// Not implemented
            }
        })
        try
        {
            val sc = SSLContext.getInstance("TLS")
            sc.init(null, trustAllCerts, java.security.SecureRandom())
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory())
            HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier)
        }
        catch (e: KeyManagementException) {
            e.printStackTrace()
        }
        catch (e: NoSuchAlgorithmException) {
            e.printStackTrace()
        }
    }

0

多分これは役立つでしょう...自己署名証明書を使用するJavaクライアントで動作します(証明書のチェックはありません)。安全ではないため、注意して開発ケースにのみ使用してください。

Apache HttpClient 4.0でSSL証明書エラーを無視する方法

HttpClientライブラリを追加するだけでAndroidで動作することを願っています...


1
いいえ、Androidバリアントに存在しない非推奨のメソッドに依存しているため、Androidでは機能しません:-(
kellyfj

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.