How to create an SSL connection using the Smack XMPP library?

送分小仙女□ 提交于 2019-12-18 13:33:58

问题


I'm building a small program that acts as an XMPP client and I am using the Smack library. Now, the server I am connecting to requires SSL (in Pidgin I have to check "Force old (port 5223) SSL"). I'm having trouble getting Smack to connect to this server. Is it possible?


回答1:


Take a look at this thread.

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

Essentially, you need to add these two lines to your code:

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

where connConfig is your ConnectionConfiguration object. Get the DummySSLSocketFactory from the Spark source code repository. All it does is accept virtually any certificate. This seemed to work for me. Good luck!




回答2:


Yes, it's quite easy to achieve. Take a look at the ConnectionConfiguration class, and in particular the setSecurityMode method which accepts a ConnectionConfiguration.SecurityMode enum as a parameter. Setting this to "required" forces Smack to use TLS.

from the Javadoc:

Securirty via TLS encryption is required in order to connect. If the server does not offer TLS or if the TLS negotiaton fails, the connection to the server will fail.




回答3:


You can achieve this by the following:

Storing the CA Certificate in Keystore

To store the certificate in a Keystore follow these steps.

Step 1: Download the bouncycastle JAR file. It can be downloaded from the here: Bouncy Castle JAVA Releases

Step 2: Use the following command to store the certificate in 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>"

Step 3: Verify the 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>"

This shall list us the certificate included in the keystore.

We have a keystore which we can use in our code.

Using the keystore

After generating this keystore, save it in the raw folder of your application. The use the below code to get the certificate handshake with the openfire server.

To create a connection with openfire using XMPP, you may need to get the config. For the same, use the below method:

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

All done..!! Just connect.. Now your connection is secured.

All follow the same in my blog at smackssl.blogspot.in



来源:https://stackoverflow.com/questions/545082/how-to-create-an-ssl-connection-using-the-smack-xmpp-library

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!