如何从 "Credential storage" 加载证书?
How to load a certificate from "Credential storage"?
我的网络代码是用 NDK (cURL + OpenSSL) 编写的,我想使用 Android 的凭据存储中的证书作为 SSL 连接的客户端证书。此外,我想向用户提供可用证书列表,以便他可以选择用于连接的证书。不幸的是,我无法从密钥存储中获取证书。
我在 Android 设备 (5.0.2) 上为 "Credential storage"(设置 -> 安全 -> ...)安装了客户端证书,但我无法访问它来自 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());
}
我做错了什么?
尝试这样的事情:
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;
}
}
安装在设备上的用户凭证可通过 Android KeyChain, not Android KeyStore
获得
The KeyChain class provides access to private keys and their corresponding certificate chains in credential storage.
使用choosePrivateKeyAlias
提示用户selecting证书。系统为用户启动 Activity
以 select 别名并通过回调 returns 别名。然后使用getPrivateKey
和getCertificate
恢复密钥和对应的证书链
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);
我的网络代码是用 NDK (cURL + OpenSSL) 编写的,我想使用 Android 的凭据存储中的证书作为 SSL 连接的客户端证书。此外,我想向用户提供可用证书列表,以便他可以选择用于连接的证书。不幸的是,我无法从密钥存储中获取证书。
我在 Android 设备 (5.0.2) 上为 "Credential storage"(设置 -> 安全 -> ...)安装了客户端证书,但我无法访问它来自 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());
}
我做错了什么?
尝试这样的事情:
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;
}
}
安装在设备上的用户凭证可通过 Android KeyChain, not Android KeyStore
获得The KeyChain class provides access to private keys and their corresponding certificate chains in credential storage.
使用choosePrivateKeyAlias
提示用户selecting证书。系统为用户启动 Activity
以 select 别名并通过回调 returns 别名。然后使用getPrivateKey
和getCertificate
恢复密钥和对应的证书链
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);