【问题标题】:How to load a certificate from "Credential storage"?如何从“凭据存储”加载证书?
【发布时间】:2018-04-01 12:42:46
【问题描述】:

我的网络代码是用 NDK (cURL + OpenSSL) 编写的,我想使用来自 Android 凭证存储的证书作为 SSL 连接的客户端证书。此外,我想向用户提供可用证书的列表,以便他可以选择用于连接的证书。很遗憾,我无法从密钥存储中获取证书。

我在我的 Android 设备 (5.0.2) 上将客户端证书安装到“凭据存储”(设置 -> 安全 -> ...),但我无法从 Java 访问它。我尝试调用以下代码,但密钥存储是空的,虽然证书安装在凭据存储中:

//KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
ks.load(null);

Enumeration<String> aliases = ks.aliases();
while(aliases.hasMoreElements()) {
    String alias = (String)aliases.nextElement();
    Log.i("app", "alias name: " + alias);
    Certificate certificate = ks.getCertificate(alias);
    Log.i("app", certificate.toString());
}

我做错了什么?

【问题讨论】:

    标签: java android android-ndk certificate credentials


    【解决方案1】:

    试试这样的:

    X509TrustManager manager = null;
    FileInputStream fs = null;
    
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    
    try
    {
        fs = new FileInputStream(System.getProperty("javax.net.ssl.trustStore")); 
        keyStore.load(fs, null);
    }
    finally
    {
        if (fs != null) { fs.close(); }
    }
    
    trustManagerFactory.init(keyStore);
    TrustManager[] managers = trustManagerFactory.getTrustManagers();
    
    for (TrustManager tm : managers)
    {
        if (tm instanceof X509TrustManager) 
        {
            manager = (X509TrustManager) tm;
            break;
        }
    }
    

    【讨论】:

      【解决方案2】:

      设备上安装的用户凭据可通过 Android KeyChain 获得,而不是 Android KeyStore

      KeyChain 类提供对私钥及其在凭证存储中的相应证书链的访问。

      使用choosePrivateKeyAlias提示用户选择证书。系统启动Activity 供用户选择别名并通过回调返回。然后使用getPrivateKeygetCertificate来恢复密钥和对应的证书链

      KeyChain.choosePrivateKeyAlias(activity, new KeyChainAliasCallback() {
                  public void alias(String alias) {               
                      //do something with the selected alias                      
                  }               
              },
              new String[] { KeyProperties.KEY_ALGORITHM_RSA, "DSA"}, // List of acceptable key types. null for any
              null,                        // issuer, null for any
              null,                        // host name of server requesting the cert, null if unavailable
              -1,                          // port of server requesting the cert, -1 if unavailable
              "");                         // alias to preselect, null if unavailable
      

      PrivateKey privateKey = KeyChain.getPrivateKey(activity, alias);
      X509Certificate chain[] = KeyChain.getCertificateChain(activity, alias);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-02
        • 1970-01-01
        • 2016-10-17
        • 1970-01-01
        • 2017-03-14
        • 2022-12-18
        • 2020-10-12
        • 1970-01-01
        相关资源
        最近更新 更多