2009-02-13 55 views
6

我正在构建一个充当XMPP客户端的小程序,我正在使用Smack库。现在,我连接的服务器需要SSL(在Pidgin中,我必须检查“Force old(port 5223)SSL”)。我无法让Smack连接到此服务器。可能吗?如何使用Smack XMPP库创建SSL连接?

回答

7

看看这个帖子。

http://www.igniterealtime.org/community/thread/37678

本质上讲,你需要将以下两行添加到您的代码:

connConfig.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled); 
connConfig.setSocketFactory(new DummySSLSocketFactory()); 

其中connConfig是你ConnectionConfiguration对象。从Spark源代码库获取DummySSLSocketFactory。它所做的只是接受任何证书。这似乎对我有用。祝你好运!

+1

这DummySSLSocketFactory允许任何证书的过去,即使它过期或不通过根CA烧焦所以我建议获取CA证书并将其存储在KeyStore中并将其添加到应用程序中并使用它。请参阅我的答案了解更多详情。 – Iqbal 2015-10-15 11:57:00

3

是的,这很容易实现。请看ConnectionConfiguration类,特别是接受ConnectionConfiguration.SecurityMode枚举作为参数的setSecurityMode方法。将其设置为“必需”将强制Smack使用TLS。

从的Javadoc:

Securirty通过TLS加密需要以连接 。如果 服务器不提供TLS或如果TLS协商失败,则连接 到服务器将失败。

3

您可以通过以下实现:

在密钥库

存放CA证书存储在密钥库证书请按照下列步骤。

第1步:下载bouncycastle JAR文件。它可以从这里下载:充气城堡的Java版本

第2步:使用以下命令来存储密钥库证书

keytool -importcert -v -trustcacerts -file "<certificate_file_with_path>" -alias "<some_name_for_certificate>" -keystore "<file_name_for_the_output_keystore>" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "<bouncy_castle_jar_file_with_path>" -storetype BKS -storepass "<password_for_the_keystore>" 

第3步:验证密钥库文件

keytool -importcert -v -list -keystore "<file_name_for_the_keystore_with_path>" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "<bouncy_castle_jar_file_with_path>" -storetype BKS -storepass "<password_for_the_keystore>" 

这将列出我们包含在密钥库中的证书。

我们有一个keystore,可以在我们的代码中使用。

使用密钥库

产生这个密钥库后,将其保存在您的应用程序的原始文件夹中。使用下面的代码来获得与openfire服务器的证书握手。

要使用XMPP创建与openfire的连接,您可能需要获取配置。出于同样的,使用下面的方法:

public ConnectionConfiguration getConfigForXMPPCon(Context context) { 
     ConnectionConfiguration config = new ConnectionConfiguration(URLConstants.XMPP_HOST, URLConstants.XMPP_PORT); 
     config.setSASLAuthenticationEnabled(false); 
     config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled); 
     config.setCompressionEnabled(false); 
     SSLContext sslContext = null; 
     try { 
      sslContext = createSSLContext(context); 
     } catch (KeyStoreException e) { 
      e.printStackTrace(); 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } catch (KeyManagementException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (CertificateException e) { 
      e.printStackTrace(); 
     } 

     config.setCustomSSLContext(sslContext); 
     config.setSocketFactory(sslContext.getSocketFactory()); 

     return config; 
} 

private SSLContext createSSLContext(Context context) throws KeyStoreException, 
      NoSuchAlgorithmException, KeyManagementException, IOException, CertificateException { 
     KeyStore trustStore; 
     InputStream in = null; 
     trustStore = KeyStore.getInstance("BKS"); 

     if (StringConstants.DEV_SERVER_IP.equals(URLConstants.XMPP_HOST) || StringConstants.TEST_SERVER_IP.equals(URLConstants.XMPP_HOST)) 
      in = context.getResources().openRawResource(R.raw.ssl_keystore_dev_test); 
     else if(StringConstants.STAGE_SERVER_IP.equals(URLConstants.XMPP_HOST) || StringConstants.STAGE2_SERVER_IP.equals(URLConstants.XMPP_HOST)) 
      in = context.getResources().openRawResource(R.raw.ssl_keystore_stage); 
     else if(StringConstants.PROD_SERVER_IP.equals(URLConstants.XMPP_HOST) || StringConstants.PROD1_SERVER_IP.equals(URLConstants.XMPP_HOST)) 
      in = context.getResources().openRawResource(R.raw.ssl_keystore_prod); 

     trustStore.load(in, "<keystore_password>".toCharArray()); 

     TrustManagerFactory trustManagerFactory = TrustManagerFactory 
       .getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
     trustManagerFactory.init(trustStore); 
     SSLContext sslContext = SSLContext.getInstance("TLS"); 
     sslContext.init(null, trustManagerFactory.getTrustManagers(), 
       new SecureRandom()); 
     return sslContext; 
} 

全部完成.. !!只要连接..现在你的连接是安全的。

所有跟随在我的博客同在smackssl.blogspot.in

+0

什么是“上下文”和“R”类? – 2016-03-30 13:58:52