代码之家  ›  专栏  ›  技术社区  ›  Androidicus

Android服务器应用程序:SSLHandshakeException(无法找到所请求目标的有效证书路径)

  •  0
  • Androidicus  · 技术社区  · 11 年前

    我正在开发一个Android应用程序,需要使用我自己的SSL证书提供一个SSL安全的TCP服务器。 我有以下文件:

    • 服务器.crt
    • server.key(专用)
    • my-ca.rt公司

    1) 证书创建:
    正如本文中所解释的,我已经使用命令行工具“keytool”从mycert.pem创建了一个BKS密钥库。将其放在应用程序的/res/raw文件夹中。我不确定如何使用私钥,但我不需要它来创建证书,是吗?

    2) 服务器代码:

    String keyStoreType = KeyStore.getDefaultType();
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    KeyStore.load(context.getResouces().openRawResource(R.raw.mykeystore), "mypass".toCharArray();
    
    String keyalg = KeyManagerFactory.getDefaultAlgorithm();
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(keyalg);
    kmf.init(keyStore, "mypass".toCharArray());
    
    
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(kmf.getKeyManagers(), null, null);
    SSLServerSocket serverSocket = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket(3333);
    
    SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
    
    //not shown: create BufferedReader from sslSocket.getInputStream(), while-loop for incoming messages
    

    3) 客户代码:
    我编写了一个包含以下代码的虚拟java客户端:

    SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
    SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("192.168.2.101", 3333);
    sslsocket.startHandshake();
    

    并通过调用:

    java-Djavax.net.ssl.trustStore=密钥库 -Djavax.net.ssl.trustStorePassword=密码客户端 传递我为服务器创建的相同密钥库。

    呼叫时 startHandshake() 客户端引发SSLHandshakeException,表示“PKIX路径生成失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到到请求目标的有效证书路径”。

    对于客户机和服务器,我使用相同的密钥库,只包含server.crt文件。这可能是问题的根源吗?我是否必须使用私钥(server.key)和/或ca证书才能完成此操作?还有其他建议吗?

    非常感谢您的帮助。提前感谢。

    1 回复  |  直到 11 年前
        1
  •  0
  •   Androidicus    11 年前

    我想我已经想通了。这是一个相当麻烦的问题,所以如果有人遇到过类似的问题,那么我们就来看看怎么办。 我通过调用以下命令创建了一个新的pkcs12密钥库,添加了server.crt、server.key和ca.crt:

    openssl pkcs12 -export -in cert.pem -inkey key.pem -out server.p12 -name server -CAfile cacert.pem -caname root
    

    Android只接受BKS文件,所以我需要转换它。使用工具portclel的直接转换不起作用,因为pkcs12到bks需要弹性城堡1.5,但android只支持弹性城堡1.46。所以我下载了两个版本的弹跳城堡。首先,我添加了1.5版,并将pkcs12转换为JRE文件(有很多答案)。

    然后我用1.46替换了1.5版,并使用portclele再次将JRE转换为BKS。

    之后,您只需要将密钥库添加到Android中的/res/raw中,并按照上面的代码所示使用它。

    希望这对某人有所帮助。