Android SSLHandshake失败 - CA证书

时间:2016-06-10 10:07:00

标签: java android ssl certificate handshake

我想保护我与套接字的SSL连接。但遗憾的是,我的CA证书存在问题。

 javax.net.ssl.SSLHandshakeException: Handshake failed
    at com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:441)
    at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:1014)
    at com.koushikdutta.async.AsyncSSLSocketWrapper$5.onDataAvailable(AsyncSSLSocketWrapper.java:194)
    at com.koushikdutta.async.Util.emitAllData(Util.java:23)
    at com.koushikdutta.async.AsyncNetworkSocket.onReadable(AsyncNetworkSocket.java:152)
    at com.koushikdutta.async.AsyncServer.runLoop(AsyncServer.java:789)
    at com.koushikdutta.async.AsyncServer.run(AsyncServer.java:627)
    at com.koushikdutta.async.AsyncServer.access$700(AsyncServer.java:41)
    at com.koushikdutta.async.AsyncServer$13.run(AsyncServer.java:569)
Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
    at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:337)
    at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:231)
    at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:115)
    at com.android.org.conscrypt.OpenSSLEngineImpl.verifyCertificateChain(OpenSSLEngineImpl.java:666)
    at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake_bio(Native Method)
    at com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:426)
    ... 8 more
Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

我的代码:

    String type = KeyStore.getDefaultType();
    KeyStore trustStore = KeyStore.getInstance(type);
    trustStore.load(null, null);
    trustStore.setCertificateEntry("ca", new CA().getCert());

    String tmfAlg = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlg);
    tmf.init(trustStore);

    try {
         SSLContext context = SSLContext.getInstance("TLS");
         context.init(null, tmf.getTrustManagers(), null);
         SSLEngine engine = context.createSSLEngine();

         AsyncSSLSocketWrapper.handshake(socketNormal, url, port, engine, tmf.getTrustManagers(), new NoopHostnameVerifier(), true, (e, socket1) -> {
// ... more 

我的证书在我的资产目录中:

    public X509Certificate getCert() throws CertificateException, IOException {
        CertificateFactory certFactory;
        certFactory = CertificateFactory.getInstance("X.509");
        InputStream inputStream = new BufferedInputStream(context.getAssets().open("pem.pem"));
        return (X509Certificate) certFactory.generateCertificate(inputStream);
    }

我的证书是使用私钥签名的,并且是自签名的。

显然,它没有证书工作......但它不安全。

编辑:

我试图将现有的BKS密钥库放在运行时动态添加:

    KeyStore trustStore = KeyStore.getInstance("BKS");
    BufferedInputStream is = new BufferedInputStream(c.getAssets().open("key.bks"));
    trustStore.load(is, "12345".toCharArray());
    Log.i("Cert", "ca " + (new CA().getCert()).getSubjectDN());

    String tmfAlg = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlg);
    tmf.init(trustStore);

    try {
        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);
        SSLEngine engine = context.createSSLEngine();

        AsyncSSLSocketWrapper.handshake(socketNormal, url, port,
        engine, tmf.getTrustManagers(), new NoopHostnameVerifier(), true, (e, socket1) -> {

但不幸的是,错误是一样的。

编辑2:

更多信息:

  • 服务器PHP使用以下命令生成此证书:

    function createSSLCert($pem_file, $pem_passphrase, $pem_dn) {
        // //create ssl cert for this scripts life.
        //Create private key
        $privkey = openssl_pkey_new();
        //Create and sign CSR
        $cert    = openssl_csr_new($pem_dn, $privkey);
        $cert    = openssl_csr_sign($cert, null, $privkey, 365 * 99);//365
    
        //Generate PEM file
        $pem = array();
        openssl_x509_export($cert, $pem[0]);
        openssl_pkey_export($privkey, $pem[1], $pem_passphrase);
        $pem = implode($pem);
    
        //Save PEM file
        //echo $pem;
        file_put_contents($pem_file, $pem);
        //chmod($pem_file, 0600);
    }
    
    
        $pem_passphrase = "XXXXX";   //Set a password here
        $pem_file = "cert.pem";    //Set a path/filename for the PEM SSL Certificate which will be created.
        //The following array of data is needed to generate the SSL Cert
        $pem_dn = array(
        "countryName" => "PL",                 //Set your country name
        "localityName" => "City",        //Ser your city name
        "organizationName" => "Firm name",  //Set your company name
        "commonName" => "CN",  //Set your full hostname.
        "emailAddress" => "admin@email.pl"  //Set your email address
        );
    
        //create ssl cert for this scripts life.
        $this->createSSLCert($pem_file, $pem_passphrase, $pem_dn);
    
  • Keystore是使用Portecle工具创建的,如: 新 - > BKS - >导入可信证书 - >我的* pem文件 - >保存

  • openssl s_client -debug -connect 10.100.0.24:5678返回:

  

未发送客户端证书CA名称       服务器临时密钥:ECDH,P-256,256位       ---       SSL握手读取1630字节并写入451字节       ---       新的,TLSv1 / SSLv3,密码是ECDHE-RSA-AES256-SHA       服务器公钥是2048位       支持安全重新协商       压缩:无       扩展:无       没有ALPN协商

Verify return code: 18 (self signed certificate)

加上一些关于证书的私人信息

0 个答案:

没有答案