アプリケーションにクライアント証明書が埋め込まれたWebビューを何日か使用してみましたが、Android sdkはそれを行う方法を提供していないようです。サーバーによって送信されたチャレンジをインターセプトしますか?クライアント証明書でWebViewを使用してhttpsリクエストを行う方法はありますか?
私もあなたの問題に興味があるので、WebViewとWebViewClientのドキュメントを確認しましたが、実際に必要なメソッド(ClientCertRequestHandler)がパブリックAPI。
Android WebViewを使用してクライアント証明書で安全なサーバーに接続する
Androidセキュリティディスカッションで検索すると、通話が実際に利用できないことが確認されます。
https://groups.google.com/forum/#!msg/Android-security-discuss/0hzTGaA9swQ/1Oqc8UpGLH8J
そして
Android 4.0リリースには、ブラウザでのクライアント証明書認証のサポートが含まれています。
(参照: https://code.google.com/p/Android/issues/detail?id=8196 )
webViewsについては言及されていません:(
キーチェーンに証明書をロードするいくつかの新しいAPIがありますが、
http://developer.Android.com/reference/Android/security/KeyChain.htmlhttp://nelenkov.blogspot.it/2011/11/using-ics-keychain- api.html
webViewがそれらを使用するかどうかは明らかではありません...したがって、KeyChainクラスを試して、正しく認証できるかどうかを確認する必要があると思います(これをテストする簡単な方法がないので、自分で行います)。
KeyChainがWebViewsで動作しない場合、完全な回避策から遠く離れたいくつかの問題に要約できます。
ソリューション1:
とにかくClientCertRequestHandlerを使用します(非表示としてマークされていますが、明らかにまだ使用可能です)。
https://code.google.com/p/Android/issues/detail?id=53491
ただし、作成したとしても、Android開発チームはメソッドを予告なしに変更/削除する可能性があり、アプリがSOの将来のリリースで機能しなくなる可能性があります。
ソリューション2:
ターゲットをAndroid 4.0以降)に制限できる場合、太字の(そしてありそうもない...)解決策は、ファイルスキームを使用してローカルストレージからWebviewに証明書をロードすることです:
しかし、ブラウザと同じようにWebビューが動作することを強く疑います...
ソリューション3:(これは機能するはずですが、多大な労力を必要とします)
HTTPClientまたはHttpURLConnectionを使用してバックグラウンドですべてのhttps接続を処理し、データをWebViewに渡します。
http://chariotsolutions.com/blog/post/https-with-client-certificates-on/
あなたは私の同情を持っています。
Webビュー内のssl証明書リクエストを無視する必要があるだけの場合、これはLollipopで私のために機能しました:
Webビュークライアント内で、以下を上書きします。
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed(); // Ignore SSL certificate errors
}
これは、qa/dev/stage環境に対するWebviewのデバッグに役立ちます。
API 21(Android Lollipop)以降では、WebViewClient.onReceivedClientCertRequest(WebView view、ClientCertRequest request)をオーバーライドできます。このメソッドでは、秘密鍵と証明書チェーンを取得するためにキーマネージャーを使用して、request.proceed()を呼び出します。
SSL証明書の検証を適切に処理して、更新されたセキュリティポリシーに従ってアプリがGoogle Playから拒否されないようにするには、サーバーによって提示された証明書が期待に応える場合は常にSslErrorHandler.proceed()を呼び出すようにコードを変更し、そうでない場合はSslErrorHandler.cancel()を呼び出します。
たとえば、警告ダイアログを追加してユーザーに確認し、Googleが警告を表示しないようにしています。
@Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
String message = "SSL Certificate error.";
switch (error.getPrimaryError()) {
case SslError.SSL_UNTRUSTED:
message = "The certificate authority is not trusted.";
break;
case SslError.SSL_EXPIRED:
message = "The certificate has expired.";
break;
case SslError.SSL_IDMISMATCH:
message = "The certificate Hostname mismatch.";
break;
case SslError.SSL_NOTYETVALID:
message = "The certificate is not yet valid.";
break;
}
message += " Do you want to continue anyway?";
builder.setTitle("SSL Certificate Error");
builder.setMessage(message);
builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
handler.proceed();
}
});
builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
handler.cancel();
}
});
final AlertDialog dialog = builder.create();
dialog.show();
}
この変更後、警告は表示されなくなります。
Android 4.4のChroniumベースのWebViewはバグを導入しました:サーバーがクライアント証明書をリクエストすると、WebViewは読み込みプロセスを停止します。onPageFinished-メソッドはすぐに呼び出されますが、ページは表示されません。
Webviewでクライアント証明書にアクセスできません。同じために発生したGoogleの問題があります。 https://code.google.com/p/Android/issues/detail?id=53491
自己署名SSL証明書が機能しています
この回答を確認してください https://stackoverflow.com/a/49003522/50586