【问题标题】:How Can I Access an SSL Connection Through Android?如何通过 Android 访问 SSL 连接?
【发布时间】:2011-09-20 10:25:14
【问题描述】:

我开始学习一个没有针对 Android 的教程并得到了这个:

    System.setProperty("javax.net.ssl.trustStore", "truststore");
    System.setProperty("javax.net.ssl.trustStorePassword", "password");

    SSLSocketFactory ssf = (SSLSocketFactory) SSLSocketFactory.getDefault();
    try {
        Socket s = ssf.createSocket("192.168.2.11", 6543);
        PrintWriter out = new PrintWriter(s.getOutputStream());
        while (true){
            out.println("SSL TEST");
            Log.d("DATA", "DATA SENT");
        }



    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

我想这可以归结为几个问题:

  1. 我没有创建自己的信任库,但是在网上搜索教程和东西时,我不知道如何创建一个。有没有办法可以创建或修改信任库以在其中包含我需要的证书? (如果这有什么不同,我使用的是自签名证书)

  2. 如何使 SSL 握手顺利进行?现在,我得到的错误是:

    javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:找不到证书路径的信任锚。

    老实说,我真的不明白这是什么意思。

  3. 我需要在我的 Android 设备上修改哪些设置或文件以确保可以进行此连接?

【问题讨论】:

  • 您可能应该从 Android 的方式开始,而不是尝试修改非 Android 技术。
  • 我还尝试将我的服务器上的密钥库文件放在我的 jdk/jre/lib/security 文件夹中,然后更改信任库位置和密码以匹配它,我得到了相同的例外。
  • 等等!什么是“Android 方式”?
  • 如果我大声呼救,是否意味着人们会更快地回答我的问题?此外,我目前的方法是尝试从 SSLContext 中获取 SSLSocketFactory,我正在尝试使用我的密钥库对其进行初始化。仍然在这里解决问题,但它可能很有希望。

标签: java android sockets ssl ssl-certificate


【解决方案1】:

1) 视情况而定。您在服务器端是否有自签名证书,并且您正在尝试向 android 设备验证您的身份?还是您在 android 端尝试验证您对服务器的身份?如果是前者,那么请看这个链接:http://www.codeproject.com/KB/android/SSLVerification_Android.aspx?display=Mobile

您需要特别注意生成 KeyStore 文件的位置。

2) 您收到该错误的原因是因为它不信任您正在连接的服务器,或者因为您没有正确创建信任库,或者您正在连接的服务器的证书尚未添加到信任库.你到底想连接什么?

3) 确保 manifest.xml 中有 <uses-permission android:name="android.permission.INTERNET" />

编辑 抱歉,请查看我对第一段所做的更改。

这是初始化密钥库和信任库的部分

SSLcontext sslContext = SSLContext.getDefault();

KeyStore trustSt = KeyStore.getInstance("BKS");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
InputStream trustStoreStream = this.getResources().openRawResource(R.raw.truststore);
trustSt.load(trustStoreStream, "<yourpassword>".toCharArray());
trustManagerFactory.init(trustStre);

KeyStore keyStore = KeyStore.getInstance("BKS");
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
InputStream keyStoreStream = this.getResources().openRawResource(R.raw.keystore);
keyStore.load(keyStoreStream, "<yourpassword>".toCharArray());
keyManagerFactory.init(keyStore, "<yourpassword>".toCharArray());

sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

【讨论】:

  • [+1] 1) 我会对此进行调查,不过(在查看此网站之前)我不确定我是否理解密钥库和信任库之间的区别。 2)我可能没有正确创建信任库...我在 JRE 中使用了 keytool 功能 3)看起来我至少正确地完成了这部分:0)
  • 嗨,对不起,我在第一段中写错了,请查看更改。
  • 我认为信任库和密钥库的区别是信任库是我信任的证书列表,所以如果我在android端,我想拥有服务器证书在我的信任商店。密钥库是我保存凭据以向服务器验证的地方。在服务器端,信任库是我保存我信任的客户端列表的地方,而密钥库是我保存自己的凭据的地方。
  • 你也在做客户端认证吗? (android 设备需要证书吗?)一旦我知道了这一点,我就可以用一些代码编辑我的响应。
  • sigh 这并没有解决它,我仍然得到我原来帖子中详述的相同异常。那么现在呢?
【解决方案2】:

除非对等方使用自签名证书,否则您不需要自己的信任库。 JRE 附带一个默认使用的信任库,它信任所有主要 CA 颁发的证书。

【讨论】:

  • @Matt 所以你需要创建一个信任库。从JDK中复制一份;将服务器证书导出到文件中;并将其导入新的信任库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-27
  • 1970-01-01
  • 2016-09-20
  • 2017-10-12
  • 1970-01-01
相关资源
最近更新 更多