generateCertificate()时的CertificateException
我正在开发我的Android应用程序。 我试图从我的证书文件流生成X509Certificate实例,但获取CertificateException
,这是我的简单代码:
import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; ... public class CertMgr { //my certification file 'mycert.p12' located in my app internal storage File certFile = GET_CERT(); X509Certificate cert = null; try { FileInputStream fis = new FileInputStream(certFile); BufferedInputStream bis = new BufferedInputStream(fis); CertificateFactory cf = CertificateFactory.getInstance("X.509"); if(bis.available() > 0){ //I got CertificateException here, see the stack trace cert = (X509Certificate) cf.generateCertificate(bis); //line nr 150 } }catch(...) {...} ... }
堆栈跟踪:
javax.security.cert.CertificateException: org.apache.harmony.security.asn1.ASN1Exception: ASN.1 Sequence: mandatory value is missing at [4] 11-11 17:30:20.731: W/System.err(11529): at javax.security.cert.X509Certificate.getInstance(X509Certificate.java:94) 11-11 17:30:20.731: W/System.err(11529): at javax.security.cert.X509Certificate.getInstance(X509Certificate.java:213) 11-11 17:30:20.731: W/System.err(11529): at com.my.app.CertMgr.getCert(CertMgr.java:150)
有人可以向我解释为什么我会得到这个例外吗?
PS:这是我从Android SDK X509Certificate , CertificateFactory使用的类
如果您对我为什么这样做感到好奇,原因是我希望我的应用程序能够通过以下代码安装证书( mycert.p12 )(如果上面的代码工作正常):
Intent installIntent = KeyChain.createInstallIntent(); installIntent.putExtra(KeyChain.EXTRA_CERTIFICATE, cert.getEncoded()); installIntent.putExtra(KeyChain.EXTRA_NAME, MY_CERT); startActivityForResult(installIntent, INSTALL_KEYCHAIN_CODE);
您正在尝试读取PKCS#12数据结构,因为它是X509证书。 PKCS#12标准指定了一种数据结构,它可以捆绑多个证书和私钥,可选择受密码保护。
要读取PKCS#12数据,您需要使用KeyStore加载它。 此代码段显示如何列出PCKS#12文件的所有条目:
KeyStore keyStore = KeyStore.getInstance("PKCS12"); File p12File = GET_CERT(); FileInputStream fis = new FileInputStream(p12File); BufferedInputStream bis = new BufferedInputStream(fis); keyStore.load(bis, password.toCharArray()); // password is the PKCS#12 password. If there is no password, just pass null Enumeration aliases = keyStore.aliases(); while (aliases.hasMoreElements()) { String alias = aliases.nextElement(); /* Do something with the keystore entry */ }
KeyStore条目可以是私钥,具有或不具有关联的证书链(即,从根证书到对应于私钥的证书的证书序列),或可信证书。 您可以通过KeyStore.isKeyEntry
和KeyStore.isCertificateEntry
方法确定条目类型。
根据您提供的KeyChain意图,您似乎希望在密钥链中添加新的受信任的根CA证书。 因此,我认为您应该列出PKCS#12文件的证书条目。
编辑(2013年12月12日)
如何从密钥库获取可信证书:
String alias = aliases.nextElement(); if (keyStore.isCertificateEntry(alias)) { // keep only trusted cert entries Certificate caCert = keyStore.getCertificate(alias) byte[] extraCertificate = caCert.getEncoded(); Intent installIntent = KeyChain.createInstallIntent(); installIntent.putExtra(KeyChain.EXTRA_CERTIFICATE, extraCertificate); installIntent.putExtra(KeyChain.EXTRA_NAME, MY_CERT); startActivityForResult(installIntent, INSTALL_KEYCHAIN_CODE); }