由于ICS Android支持通过KeyChain API对系统密钥库和可信CA进行统一访问。
当我尝试使用来自此源的私钥进行客户端证书身份验证时,它非常好但是让我遇到麻烦。
我在这里查了一些答案,我找到的最好的东西是:Android 4.0 SSL Authentication
它指的是4.0并提供以下编码:
更新 - 此编码错误 - 它不适用于4.1+
String alias = "test";
KeyStore memoryKeyStore = KeyStore.getInstance("BKS");
memoryKeyStore.load(null);
X509Certificate[] chain = KeyChain.getCertificateChain(getApplicationContext(),alias);
PrivateKey key = KeyChain.getPrivateKey(getApplicationContext(),alias);
memoryKeyStore.setKeyEntry(alias, key.getEncoded(), chain);
然而,这在4.1中不起作用,因为当调用getEncoded()方法并且无法初始化KeyStore时,KeyChain.getPrivateKey()返回的PrivateKey对象返回null。
在4.1中还有其他方法吗?
更新 - 这里是定义自己的KeyStore和KeyStoreSpi实现的正确方法 这里是KeyStore和KeyStoreSpi的示例实现:
KeyStoreSpi实施:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.Key;
import java.security.KeyStoreException;
import java.security.KeyStoreSpi;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.security.PrivateKey;
public class KeyChainProxy extends KeyStoreSpi {
private String alias = null;
private PrivateKey privateKey = null;
private Certificate[] certChain = null;
public KeyChainProxy(String alias, PrivateKey privateKey, Certificate[] certChain) {
this.alias = alias;
this.privateKey = privateKey;
this.certChain = certChain;
}
@Override
public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException {
return privateKey;
}
@Override
public Certificate[] engineGetCertificateChain(String alias) {
return certChain;
}
@Override
public Certificate engineGetCertificate(String alias) {
return certChain[0];
}
@Override
public Date engineGetCreationDate(String alias) {
return new Date();
}
@Override
public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException {
throw new KeyStoreException("Not Implemented");
}
@Override
public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException {
throw new KeyStoreException("Not Implemented");
}
@Override
public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException {
throw new KeyStoreException("Not Implemented");
}
@Override
public void engineDeleteEntry(String alias) throws KeyStoreException {
throw new KeyStoreException("Not Implemented");
}
@Override
public Enumeration<String> engineAliases() {
List<String> list = new ArrayList<String>();
list.add(alias);
return Collections.enumeration(list);
}
@Override
public boolean engineContainsAlias(String alias) {
return alias != null && alias.equals(this.alias);
}
@Override
public int engineSize() {
return 1;
}
@Override
public boolean engineIsKeyEntry(String alias) {
return true;
}
@Override
public boolean engineIsCertificateEntry(String alias) {
return false;
}
@Override
public String engineGetCertificateAlias(Certificate cert) {
return null;
}
@Override
public void engineStore(OutputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException {
}
@Override
public void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException {
}
}
KeyStore实施:
import java.security.KeyStore;
import java.security.KeyStoreSpi;
import java.security.Provider;
public class KeyChainKeystore extends KeyStore {
public KeyChainKeystore(KeyStoreSpi keyStoreSpi, Provider provider, String type) {
super(keyStoreSpi, provider, type);
try {
load(null, null);
} catch (Exception e) {
// ignore - our spi doesn't do anything
}
}
}
谢谢
瓦西
答案 0 :(得分:3)
KeyChain旨在保护您的私钥。
因此,您可以获取对私钥的引用,并在您的应用程序中使用该私钥进行身份验证,加密......但您永远无法访问实际的私钥数据。
因此,您无法导出私钥 - 这就是您要尝试的内容。