generateCertificate()时的CertificateException [英] CertificateException when generateCertificate()
问题描述
我正在开发我的Android应用程序。我正在尝试从我的证书文件流生成 X509Certificate 实例,但获取 CertificateException
,这是我的简单代码:
I am developing my android app. I am trying to generate the X509Certificate instance from my certificate file stream, but get CertificateException
, here is my simple code:
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)
有人可以向我解释为什么我会得到这个例外吗?
Could someone please explain to me why I get this exception?
PS:以下是我在Android SDK中使用的课程 X509Certificate , CertificateFactory
P.S.: Here are the classes I am using from Android SDK X509Certificate , CertificateFactory
如果您对我的原因感到好奇这样做的原因是我希望我的应用程序能够通过以下代码安装证书( mycert.p12 )(如果上面的代码工作正常):
If you are curious about why I am doing this, the reason is that I want my app to be able to install the certificate(mycert.p12) by the following code (if above code is working properly):
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 标准指定了一个数据结构,它可以捆绑多个证书和私钥,可选择受密码保护。
You are trying to read a PKCS#12 data structure as it was a X509 certificate. The PKCS#12 standard specifies a data structure which can bundle multiple certificates and private keys, optionally protected by a password.
为了读取PKCS#12数据你需要使用 KeyStore 加载它。此代码段显示如何列出PCKS#12文件的所有条目:
In order to read the PKCS#12 data you need to load it with a KeyStore. This code snippet show how list all entries of the PCKS#12 file:
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<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
/* Do something with the keystore entry */
}
KeyStore条目可以是私钥,具有或不具有关联的证书链(即,从根证书到对应于私钥的证书的证书序列),或者是可信证书。您可以通过 KeyStore.isKeyEntry
和 KeyStore.isCertificateEntry
方法确定条目类型。
KeyStore entries can be private key, with or without an associated certificate chain (i.e. a sequence of certificate from the root certificate to the certificate corresponding to the private key), or a trusted certificate. You can determine the entry type by the KeyStore.isKeyEntry
and KeyStore.isCertificateEntry
methods.
根据您提供的KeyChain意图,您似乎希望在密钥链中添加新的受信任的根CA证书。因此,我认为您应该列出PKCS#12文件的证书条目。
According to the KeyChain intent you gave, it seems you want to add a new trusted Root CA certificate in the key chain. Therefore I think you should list the certificate entries of the PKCS#12 file.
编辑(2013年12月12日)
如何从密钥库获取可信证书:
How to get a trusted certificate from the keystore:
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);
}
这篇关于generateCertificate()时的CertificateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!