[英]How to store the certificate and private key in the keystore of SSL context?
我正在建立一个客户端服务器模型,客户端是一个与apache tomcat上的服务器通信的android应用程序,双方都使用SSL证书进行身份验证。 我通过以下命令为客户端创建了证书
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
openssl pkcs12 -export -name myservercert -in server.crt -inkey server.key -out keystore.p12
keytool -importkeystore -destkeystore mykeystore.jks -srckeystore keystore.p12 -srcstoretype pkcs12 -alias myservercert
现在,我有一个具有私有密钥和证书的myservercert密钥库。 这需要用于客户端身份验证。 因此,我需要将此添加到客户端的SSLcontext的密钥库中。 所以下面的代码。
public HttpClient myHttpsClient() {
HttpClient client = null;
char[] passphrase = "password".toCharArray();
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
CertificateFactory clientcf = CertificateFactory.getInstance("X.509");
InputStream caInput = context.getResources().openRawResource(R.raw.server);
InputStream clientcert = context.getResources().openRawResource(R.raw.client);
Certificate ca;
Certificate clientca;
try {
clientca = clientcf.generateCertificate(clientcert);
ca = cf.generateCertificate(caInput);
System.out.println("ca="+ ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
clientcert.close();
}
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStoreclient = KeyStore.getInstance(keyStoreType);
keyStoreclient.load(null, null);
keyStoreclient.setCertificateEntry("ca", clientca);
// Create a KeyStore containing our trusted CAs
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String kmfAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlgorithm);
kmf.init(keyStoreclient,passphrase);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
MySSLSocketFactory socketFactory = new MySSLSocketFactory(context);//,new BrowserCompatHostnameVerifier());
client = createHttps(socketFactory);
} catch (Exception e) {
e.printStackTrace();
}
return client;
当我执行代码时,我在运行时异常下得到了..
07-08 22:37:52.834: W/System.err(4422): java.security.cert.CertificateException: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
07-08 22:37:52.944: I/Choreographer(4422): Skipped 57 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.044: I/Choreographer(4422): Skipped 49 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.134: I/Choreographer(4422): Skipped 46 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.324: I/Choreographer(4422): Skipped 124 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.434: I/Choreographer(4422): Skipped 48 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.504: I/Choreographer(4422): Skipped 40 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.544: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509CertificateFactory.engineGenerateCertificate(OpenSSLX509CertificateFactory.java:272)
07-08 22:37:53.544: W/System.err(4422): at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:195)
07-08 22:37:53.554: W/System.err(4422): at com.danielwirelesssoftware.utility.CreateHttpsClient.myHttpsClient(CreateHttpsClient.java:67)
07-08 22:37:53.584: I/Choreographer(4422): Skipped 35 frames! The application may be doing too much work on its main thread.
07-08 22:37:53.624: W/System.err(4422): at com.danielwirelesssoftware.ServerOperations.LoginManager.doInBackground(LoginManager.java:121)
07-08 22:37:53.684: W/System.err(4422): at com.danielwirelesssoftware.ServerOperations.LoginManager.doInBackground(LoginManager.java:1)
07-08 22:37:53.694: W/System.err(4422): at android.os.AsyncTask$2.call(AsyncTask.java:288)
07-08 22:37:53.694: W/System.err(4422): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-08 22:37:53.714: W/System.err(4422): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
07-08 22:37:53.714: W/System.err(4422): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
07-08 22:37:53.714: W/System.err(4422): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
07-08 22:37:53.824: I/Choreographer(4422): Skipped 93 frames! The application may be doing too much work on its main thread.
07-08 22:37:54.764: W/System.err(4422): at java.lang.Thread.run(Thread.java:841)
07-08 22:37:54.764: W/System.err(4422): Caused by: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
07-08 22:37:54.774: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser.generateItem(OpenSSLX509CertificateFactory.java:113)
07-08 22:37:54.774: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509CertificateFactory.engineGenerateCertificate(OpenSSLX509CertificateFactory.java:270)
07-08 22:37:54.774: W/System.err(4422): ... 10 more
07-08 22:37:54.774: W/System.err(4422): Caused by: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
07-08 22:37:55.274: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509Certificate.fromX509DerInputStream(OpenSSLX509Certificate.java:71)
07-08 22:37:55.274: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509CertificateFactory$1.fromX509DerInputStream(OpenSSLX509CertificateFactory.java:224)
07-08 22:37:55.274: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509CertificateFactory$1.fromX509DerInputStream(OpenSSLX509CertificateFactory.java:214)
07-08 22:37:55.284: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser.generateItem(OpenSSLX509CertificateFactory.java:104)
07-08 22:37:55.284: W/System.err(4422): ... 11 more
07-08 22:37:55.284: W/System.err(4422): Caused by: java.lang.RuntimeException: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
07-08 22:37:55.874: W/System.err(4422): at com.android.org.conscrypt.NativeCrypto.d2i_X509_bio(Native Method)
07-08 22:37:55.874: W/System.err(4422): at com.android.org.conscrypt.OpenSSLX509Certificate.fromX509DerInputStream(OpenSSLX509Certificate.java:65)
07-08 22:37:55.874: W/System.err(4422): ... 14 more
07-08 22:37:56.394: W/System.err(4422): java.lang.NullPointerException
07-08 22:37:56.524: W/System.err(4422): at com.danielwirelesssoftware.ServerOperations.LoginManager.doInBackground(LoginManager.java:133)
07-08 22:37:57.094: W/System.err(4422): at com.danielwirelesssoftware.ServerOperations.LoginManager.doInBackground(LoginManager.java:1)
07-08 22:37:57.094: W/System.err(4422): at android.os.AsyncTask$2.call(AsyncTask.java:288)
07-08 22:37:57.094: W/System.err(4422): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
07-08 22:37:57.434: I/Choreographer(4422): Skipped 88 frames! The application may be doing too much work on its main thread.
07-08 22:37:57.454: W/System.err(4422): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
07-08 22:37:57.454: W/System.err(4422): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
07-08 22:37:57.454: W/System.err(4422): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
07-08 22:37:57.454: W/System.err(4422): at java.lang.Thread.run(Thread.java:841)
07-08 22:37:58.184: I/Choreographer(4422): Skipped 470 frames! The application may be doing too much work on its main thread.
07-08 22:37:58.294: I/Choreographer(4422): Skipped 62 frames! The application may be doing too much work on its main thread.
从上面的异常来看,看起来有些错误是该行
clientca = clientcf.generateCertificate(clientcert);
有人可以确认上述行中的任何错误。 证书的格式还是其他? 提前致谢
我自己想通了。 下面的代码对我有用。
public HttpClient myHttpsClient() {
HttpClient client = null;
char[] passphrase = "password".toCharArray();
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
CertificateFactory clientcf = CertificateFactory.getInstance("X.509");
InputStream caInput = context.getResources().openRawResource(R.raw.server);
InputStream clientcert = context.getResources().openRawResource(R.raw.clientks);
Certificate ca;
KeyStore keyStoreclient = KeyStore.getInstance("BKS");
try {
keyStoreclient.load(clientcert, "password".toCharArray());
ca = cf.generateCertificate(caInput);
System.out.println("server ca="+ ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
clientcert.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
String kmfAlgorithm = KeyManagerFactory.getDefaultAlgorithm();
KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlgorithm);
kmf.init(keyStoreclient,passphrase);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
MySSLSocketFactory socketFactory = new MySSLSocketFactory(context);//,new BrowserCompatHostnameVerifier());
client = createHttps(socketFactory);
} catch (Exception e) {
e.printStackTrace();
}
return client;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.