【问题标题】:Android - Programmatically retrieve certificate (manually installed) from keystoreAndroid - 以编程方式从密钥库中检索证书(手动安装)
【发布时间】:2017-12-10 16:43:18
【问题描述】:

在我的安卓设备上,我手动安装了一个证书,目的是让我可以访问特定的网站。

当我查看安全性 -- 用户证书时,我看到可以看到我的证书。

我的网站显示成webview,所以我必须使用下面的代码

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

在我的 loadCertificateAndPrivateKey() 函数中,我要获得这样的证书

KeyStore ks = KeyStore.getInstance("AndroidCAStore");
if (ks != null)
{
    ks.load(null, null);
    Enumeration<String> aliases = ks.aliases();
    while (aliases.hasMoreElements())
    {
        String alias = (String) aliases.nextElement();
        java.security.cert.X509Certificate cert = (java.security.cert.X509Certificate) ks.getCertificate(alias);
        if(cert.getIssuerDN().getName().contains("TOTO")){
            mCertificates = new X509Certificate[1];
            mCertificates[0] = (X509Certificate)cert;


            mPrivateKey = ??;

        }
    }

但我不知道如何获取私钥...
我试过这种方式,但关键对象为空(当我直接从我的应用程序加载我的证书时,相同的代码工作)

Key key = keyStore.getKey(alias, password.toCharArray());
if (key instanceof PrivateKey) {
    mPrivateKey = (PrivateKey)key;
}

所以我有几个问题:

  • 获取证书的方法是否正确?
  • 为什么无法使用证书密码检索私钥?
  • 如何找回这个私钥?

感谢您的回答!

【问题讨论】:

  • 你的目标是什么安卓版本?
  • 我正在 Android 6 上进行测试,如果它可以在 android 4.2.2 上运行就好了(但 API 17 = 无法访问 AndroidCAStore)。但优先考虑的是 Android 6
  • 如果您仅使用证书访问您的网站,则不需要证书私钥。您也不应该在 android 上安装私钥。私钥好像不见了,没关系
  • 问题是,如果在 request.proceed 方法中私钥为 null 或为空,我会得到 403 禁止。我发布了一个对我有用的解决方案。

标签: android ssl keystore


【解决方案1】:

我找到了这样做的方法,希望它会帮助某人。

我关注了this link,他解释了如何实现整个流程。

最后,我得到了下面的代码。 首先,定义一个 KeyChainAliasCallback 并调用显示活动的 KainChain.choosePrivateKeyAlias 以获得用户访问证书存储的权限。

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

然后,您可以从内部存储中检索私钥和证书链(您必须使用异步函数)

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


    }
};

那么,你就可以用这个功能给证书了:

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

我必须找到的最后一件事是如何只显示一次 choosePrivateKeyAlias 对话框(第一次)。

【讨论】:

    猜你喜欢
    • 2016-02-15
    • 1970-01-01
    • 2011-07-16
    • 2012-09-29
    • 2017-05-10
    • 2016-06-14
    • 2018-09-05
    • 2010-11-28
    • 2012-10-09
    相关资源
    最近更新 更多