2009-02-13 57 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