Android WebView handle onReceivedClientCertRequest

2019-03-15 19:12发布

问题:

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:

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);
        }
    };