2009-02-13 34 views
6

Tôi đang xây dựng một chương trình nhỏ hoạt động như một ứng dụng XMPP và tôi đang sử dụng thư viện Smack. Bây giờ, máy chủ tôi đang kết nối để yêu cầu SSL (trong Pidgin tôi phải kiểm tra "Force old (port 5223) SSL"). Tôi gặp sự cố khi tải Smack để kết nối với máy chủ này. Có thể không?Cách tạo kết nối SSL bằng thư viện Smack XMPP?

Trả lời

7

Hãy xem chủ đề này.

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

Về cơ bản, bạn cần phải thêm hai dòng sau để mã của bạn:

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

nơi connConfig là đối tượng ConnectionConfiguration của bạn. Lấy DummySSLSocketFactory từ kho mã nguồn Spark. Tất cả những gì nó làm là chấp nhận hầu như bất kỳ chứng chỉ nào. Điều này dường như làm việc cho tôi. Chúc may mắn!

+1

DummySSLSocketFactory này cho phép bất kỳ qua chứng chỉ, ngay cả khi nó hết hạn hoặc không bị cháy xém bởi CA gốc Vì vậy, tôi đề nghị cách tiếp cận để lấy chứng chỉ CA và lưu trữ nó trong KeyStore và thêm nó vào ứng dụng và sử dụng như vậy. Vui lòng tham khảo câu trả lời của tôi để biết thêm chi tiết. – Iqbal

3

Có, nó khá dễ dàng để đạt được. Hãy xem lớp ConnectionConfiguration và đặc biệt là phương thức setSecurityMode chấp nhận một tham số ConnectionConfiguration.SecurityMode như một tham số. Thiết lập điều này để "yêu cầu" lực lượng Smack để sử dụng TLS.

từ Javadoc:

Securirty qua TLS mã hóa được cần thiết để kết nối. Nếu máy chủ không cung cấp TLS hoặc nếu đàm phán TLS không thành công, kết nối với máy chủ sẽ không thành công.

3

Bạn có thể đạt được điều này bằng cách sau:

Lưu trữ các chứng chỉ CA trong Keystore

Để lưu trữ các chứng chỉ trong một Keystore làm theo các bước sau.

Bước 1: Tải xuống tệp JAR bouncycastle. Nó có thể được tải về từ đây: Bouncy Castle JAVA chí

Bước 2: Sử dụng lệnh sau để lưu trữ các chứng chỉ trong keystore

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>" 

Bước 3: Xác minh keystore file

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>" 

Điều này sẽ liệt kê cho chúng tôi chứng chỉ được bao gồm trong kho khóa.

Chúng tôi có kho khóa mà chúng tôi có thể sử dụng trong mã của mình.

Sử dụng keystore

Sau khi tạo keystore này, hãy lưu nó trong thư mục nguyên của ứng dụng của bạn. Sử dụng mã bên dưới để lấy chứng chỉ bắt tay với máy chủ openfire.

Để tạo kết nối với openfire bằng XMPP, bạn có thể cần phải có cấu hình. Cho cùng, sử dụng các phương pháp dưới đây:

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; 
} 

Tất cả thực hiện .. !! Chỉ cần kết nối .. Bây giờ kết nối của bạn được bảo mật.

Tất cả theo cùng trong blog của tôi tại smackssl.blogspot.in

+0

Các lớp 'Context' và' R' là gì? –

+0

@Alastair 'Context' là ngữ cảnh ứng dụng hoặc cấp lớp, bạn có thể sử dụng' this'. Và 'R' là một lớp mà từ đó tôi nhận được các kho khóa được lưu trữ trong ổ cứng của mình trong thư mục thô, bạn có thể trực tiếp chuyển tài nguyên đó vào trong bằng bất kỳ phương tiện nào khác như bạn muốn. – Iqbal

+0

Có vẻ như bạn đang làm việc trong một khuôn khổ cụ thể. Android? Tôi không, vì vậy điều này chỉ làm tôi bối rối một chút. Nhưng tôi đã tìm ra. Dù sao cũng cảm ơn bạn. –

Các vấn đề liên quan