Android无法生成证书

问题描述:

生成证书时出现问题。 以下是相关的代码。Android无法生成证书

@SuppressLint("SdCardPath") 
public HttpsURLConnection setUpHttpsConnection(String urlString) 
{ 
    try 
    { 
     CertificateFactory cf = CertificateFactory.getInstance("X.509","BC"); 

     AssetManager assManager = context.getAssets(); 
     InputStream caInput = assManager.open("testCert.pfx"); 

     KeyStore keyStore = KeyStore.getInstance("PKCS12"); 

     Certificate ca = cf.generateCertificate(caInput); 

     System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN()); 

     keyStore.load(null, null); 
     keyStore.setCertificateEntry("ca", ca); 

     String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
     TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
     tmf.init(keyStore); 

     SSLContext context = SSLContext.getInstance("TLS"); 
     context.init(null, tmf.getTrustManagers(), null); 

     URL url = new URL(urlString); 
     HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection(); 
     urlConnection.setSSLSocketFactory(context.getSocketFactory()); 

     return urlConnection; 
    } 
    catch (Exception ex) 
    { 
     Log.e("fff", "Failed to establish SSL connection to server: " + ex.toString()); 
     ex.printStackTrace(); 
     return null; 
    } 

} 

程序在随后的行提供了一个错误。

CertificateFactory cf = CertificateFactory.getInstance("X.509","BC"); 

错误跟踪;

com.android.org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory$ExCertificateException 
rer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true 
at com.android.org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory.engineGenerateCertificate(CertificateFactory.java:220) 
at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:196) 
at com.example.hilalinan.cert.ServiceCall.setUpHttpsConnection(ServiceCall.java:125) 
at com.example.hilalinan.cert.ServiceCall.doInBackground(ServiceCall.java:58) 
at android.os.AsyncTask$2.call(AsyncTask.java:295) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 
Caused by: java.lang.IllegalArgumentException: unknown object in getInstance: com.android.org.bouncycastle.asn1.ASN1Integer 
at com.android.org.bouncycastle.asn1.ASN1Sequence.getInstance(ASN1Sequence.java:98) 
at com.android.org.bouncycastle.asn1.x509.TBSCertificate.getInstance(TBSCertificate.java:64) 
at com.android.org.bouncycastle.asn1.x509.Certificate.<init>(Certificate.java:61) 
at com.android.org.bouncycastle.asn1.x509.Certificate.getInstance(Certificate.java:45) 
at com.android.org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory.readDERCertificate(CertificateFactory.java:68) 
at com.android.org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory.engineGenerateCertificate(CertificateFactory.java:215) 
... 9 more 

当我搜索这个问题时,我发现在flipoverflow中this question。我明白我的手机没有BC提供者的可信凭证。问题的OP建议,我添加BC供应商到我的手机。但即使我安装了,我如何提供其他用户安装谁正在使用我的程序。 另外,当我GOOGLE了它如何将BC添加到我的列表我找不到任何有用的东西。

有什么想法如何解决我的问题?

在此先感谢。

+2

甲'pfx'文件是一个PKCS#12文件,该文件可以包含多个证书和密钥。因此,您必须直接将其作为PKCS12密钥库加载,而不要尝试从中生成证书对象! – Robert

+0

我不明白我不太熟悉这个话题。你可以再详细一点吗?如果我不能生成证书,我该如何访问https服务?我应该使用'crt'文件吗? – Hilal

pfx文件是一个PKCS#12文件,其中可能包含多个证书和密钥(除非更改了文件扩展名)。

您使用的代码需要一个简单证书(.cer,.crt.der)文件。

因此,你必须直接加载它作为PKCS12密钥库,而不是尝试从它生成证书对象:

InputStream caInput = assManager.open("testCert.pfx"); 
String pfxPassword = "password"; // change it to the correct password 
keyStore.load(caInput, pfxpassword.toCharArray()); 
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); 
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); 
tmf.init(keyStore); 
+0

谢谢它避免了这个问题。但现在我正在得到另一个例外。 javax.net.ssl.SSLPeerUnverifiedException:主机名10.0.0.35未验证 – Hilal

+0

看起来您在网络服务器上使用的证书不包含正确的主机名(本例中为“10.0.0.35”)。有可能会禁用Android中的主机名验证,但这会让您的应用容易受到攻击。最好用正确的主机名重新创建Web服务器的证书。 – Robert

+0

非常感谢!没错,证书可能没有正确的主机名。希望它能在我们改正之后解决。再次感谢 – Hilal