繁体   English   中英

如何将证书和私钥存储在SSL上下文的密钥存储区中?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM