2011-06-22 123 views
11

我开始关注,这不是针对Android套管的教程,并得到这个:如何通过Android访问SSL连接?

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: Trust anchor for certification path not found. 
    

    老实说,我真的不明白这意味着什么。

  3. 我需要什么样的设置或文件来修改自己的Android设备上,以确保这方面发生的呢?

+0

你或许应该刚开始与Android的方式来做到这一点,而不是试图修改非Android技术。 –

+0

我也尝试将我从服务器获得的keystore文件放在我的jdk/jre/lib/security文件夹中,然后更改信任存储位置和密码以匹配该文件,并且我得到了相同的异常。 – Matt

+0

等待!什么是“Android的方式”? – Matt

回答

10

1)这取决于。你有在服务器端的自签名证书,你正在尝试验证你的身份到Android设备?还是你在android端试图验证你的服务器的标识?如果是前者,那么请访问以下链接:http://www.codeproject.com/KB/android/SSLVerification_Android.aspx?display=Mobile

你要特别注意的地方,使密钥存储文件。

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); 
+0

[+1] 1)尽管(在查看本网站之前)我会调查一下,但我不确定我是否理解keystore和truststore之间的区别。 2)我可能没有正确创建信任库......我在JRE 中使用了keytool功能3)看起来像我至少得到了这个部分是正确的:0) – Matt

+1

嗨,对不起,我在第一段中犯了一个错误,请查看更改。 – Otra

+2

我认为信任存储和密钥库之间的区别在于信任存储是我信任的证书列表,所以如果我在android端,我希望在我的信任存储中拥有服务器证书。密钥库是我保持我的凭据验证服务器的地方。在服务器端,信任存储是我保存我信任的客户端列表的地方,而密钥存储是我保存自己的凭据的位置。 – Otra

1

,除非对方是使用自签名certifictes你不需要自己信任的一部分。 JRE附带默认使用的信任库,它信任所有主要CA颁发的证书。

+2

但我正在使用自签名证书... – Matt

+0

@Matt,因此您需要创建一个信任库。从JDK复制一个;将服务器证书导出到文件中;并将其导入新的信任库。 – EJP