Android - Programmatically retrieve certificate (manually installed) from keystore

99封情书 提交于 2019-12-05 14:16:09

I found the way to do that, hope that it'll help somebody.

I followed this link that explain how to implement the entire processus.

Finally, I've got the code bolow. First, define a KeyChainAliasCallback and call the KainChain.choosePrivateKeyAlias that display an activity to have the user authorization to access certificates store.

KeyChainAliasCallback keyChainAliasCallback = new KeyChainAliasCallback() {
    @Override
    public void alias(@Nullable String s) {
        Log.d(TAG, "selected alias = " + s);
        asyncTask.execute();
    }
};
KeyChain.choosePrivateKeyAlias(this, keyChainAliasCallback, null, null, null, -1, CERT_ALIAS);

Then, you're able to retrieve private key and certificates chains from the internal store (you have to use an async function)

AsyncTask<Void, Void, Boolean> asyncTask = new AsyncTask<Void, Void, Boolean>() {

    private Exception error;

    @Override
    protected Boolean doInBackground(Void... arg) {
        try {

            PrivateKey pk = KeyChain.getPrivateKey(mContext, CERT_ALIAS);
            X509Certificate[] chain = KeyChain.getCertificateChain(mContext, CERT_ALIAS);

            byte[] data = "foobar".getBytes("ASCII");
            Signature sig = Signature.getInstance("SHA1withRSA");
            sig.initSign(pk);
            sig.update(data);
            byte[] signed = sig.sign();

            PublicKey pubk = chain[0].getPublicKey();
            sig.initVerify(pubk);
            sig.update(data);
            boolean valid = sig.verify(signed);
            Log.d(TAG, "signature is valid: " + valid);

            if(valid) {
                mPrivateKey = pk;
                mCertificates = chain;
            }

            return valid;
        } catch (Exception e) {
            e.printStackTrace();
            error = e;

            return null;
        }
    }

    @Override
    protected void onPostExecute(Boolean valid) {
        if (error != null) {
            Toast.makeText(mContext, "Error: " + error.getMessage(),
                    Toast.LENGTH_LONG).show();

            return;
        } else {
            Toast.makeText(mContext, "Signature is valid: " + valid,
                    Toast.LENGTH_SHORT).show();
            mWebView.loadUrl("https://blablabla.com");
        }


    }
};

Then, you're able to give certificate with this function :

@Override
public void onReceivedClientCertRequest(WebView view, final ClientCertRequest request) {
    request.proceed(mPrivateKey, mCertificates);
}

Last thing I have to find is how to display the choosePrivateKeyAlias dialog just one time (the first).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!