如何使用 Smack XMPP 库创建 SSL 连接?

发布于 2024-07-14 03:27:49 字数 224 浏览 5 评论 0原文

我正在构建一个充当 XMPP 客户端的小程序,并且我正在使用 Smack 图书馆。 现在,我连接的服务器需要 SSL(在 Pidgin 中我必须选中“强制旧(端口 5223)SSL”)。 我无法让 Smack 连接到该服务器。 是否可以?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

抚笙 2024-07-21 03:27:50

您可以通过以下方式实现此目的:

将 CA 证书存储在密钥库中

要将证书存储在密钥库中,请按照以下步骤操作。

第 1 步:下载 bouncycastle JAR 文件。 可以从这里下载:Bouncy Castle JAVA Releases

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

keytool -importcert -v -trustcacerts -file ""   -alias“<证书的名称>”   -keystore "<输出密钥库的文件名>"   -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath“”   -storetype BKS -storepass "" 
  

第 3 步:验证密钥库文件

keytool -importcert -v -list -keystore ""   -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath“”   -storetype BKS -storepass "" 
  

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

我们有一个可以在代码中使用的密钥库。

使用密钥库

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

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

public ConnectionConfiguration getConfigForXMPPCon(上下文上下文){ 
          ConnectionConfiguration config = new ConnectionConfiguration(URLConstants.XMPP_HOST, URLConstants.XMPP_PORT); 
          config.setSASLAuthenticationEnabled(假); 
          config.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled); 
          config.setCompressionEnabled(false); 
          SSLContext sslContext = null; 
          尝试 { 
              sslContext = createSSLContext(上下文); 
          } 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()); 

          返回配置; 
   } 

  private SSLContext createSSLContext(Context context) 抛出 KeyStoreException, 
              NoSuchAlgorithmException、KeyManagementException、IOException、CertificateException { 
          密钥库信任库; 
          输入流= 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); 
          否则 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); 
          否则 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, "".toCharArray()); 

          TrustManagerFactory trustManagerFactory = TrustManagerFactory 
                  .getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
          trustManagerFactory.init(trustStore); 
          SSLContext sslContext = SSLContext.getInstance("TLS"); 
          sslContext.init(null, trustManagerFactory.getTrustManagers(), 
                  新的 SecureRandom()); 
          返回 sslContext; 
  } 
  

全做完了..!! 只需连接.. 现在您的连接已安全。

全部遵循我的博客 smackssl.blogspot 中的相同内容.in

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

诺曦 2024-07-21 03:27:50

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

来自 Javadoc:

通过 TLS 加密确保安全
需要连接。 如果
服务器不提供 TLS 或者如果
TLS 协商失败,连接
到服务器将会失败。

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.

吻泪 2024-07-21 03:27:49

看看这个线程。

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

本质上,您需要将这两行添加到您的代码中:

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

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

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文