Android WebView handle onReceivedClientCertRequest

2019-03-15 18:30发布

I'm developing an Android app using Client Certificate Authentication within WebView. The certificate (cert.pfx) and password are embedded in the application.

When executing Client Certificate Authentication request with ajax call in the WebView, the following function getting called :

@Override
public void onReceivedClientCertRequest(WebView view, final ClientCertRequest request) {}

As I understend I need to call :

request.proceed(PrivateKey privateKey, X509Certificate[] chain)

Any idea how to create the PrivateKey and X509Certificate objects from the embedded certificate in order to proceed with the request. BTW, is this the correct way to implement Client Certificate Authentication on Android app ? if no, please advice.

1条回答
手持菜刀,她持情操
2楼-- · 2019-03-15 19:35

Solved it using KeyStore to obtain the PrivateKey and X509Certificate objects :

    private X509Certificate[] mCertificates;
    private PrivateKey mPrivateKey;

    private void loadCertificateAndPrivateKey() {
          try {
                InputStream certificateFileStream = getClass().getResourceAsStream("/assets/cert.pfx");

                KeyStore keyStore = KeyStore.getInstance("PKCS12");
                String password = "password";
                keyStore.load(certificateFileStream, password != null ? password.toCharArray() : null);

                Enumeration<String> aliases = keyStore.aliases();
                String alias = aliases.nextElement();

                Key key = keyStore.getKey(alias, password.toCharArray());
                if (key instanceof PrivateKey) {
                    mPrivateKey = (PrivateKey)key;
                    Certificate cert = keyStore.getCertificate(alias);
                    mCertificates = new X509Certificate[1];
                    mCertificates[0] = (X509Certificate)cert;
                 }

                 certificateFileStream.close();

            } catch (Exception e) {
                 Log.e(TAG, e.getMessage());
         }
    }


    private WebViewClient mWebViewClient = new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return false;
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            handler.proceed();
        }

        @Override
        public void onReceivedClientCertRequest(WebView view, final ClientCertRequest request) {
            if (mCertificates == null || mPrivateKey == null) {
                loadCertificateAndPrivateKey();
            } 
            request.proceed(mPrivateKey, mCertificates);
        }
    };
查看更多
登录 后发表回答