java 如何使用 Smack XMPP 库创建 SSL 连接?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/545082/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create an SSL connection using the Smack XMPP library?
提问by staffan
I'm building a small program that acts as an XMPP client and I am using the Smacklibrary. 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?
我正在构建一个充当 XMPP 客户端的小程序,我正在使用Smack库。现在,我要连接的服务器需要 SSL(在 Pidgin 中,我必须检查“Force old (port 5223) SSL”)。我在让 Smack 连接到此服务器时遇到问题。是否可以?
回答by
Take a look at this thread.
看看这个线程。
http://www.igniterealtime.org/community/thread/37678
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!
其中 connConfig 是您的 ConnectionConfiguration 对象。从 Spark 源代码存储库中获取 DummySSLSocketFactory。它所做的只是接受几乎任何证书。这似乎对我有用。祝你好运!
回答by Iqbal Shirol
You can achieve this by the following:
您可以通过以下方式实现此目的:
Storing the CA Certificate in Keystore
将 CA 证书存储在 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
步骤 1:下载 bouncycastle JAR 文件。可以从这里下载:Bouncy Castle JAVA Releases
Step 2:Use the following command to store the certificate in keystore
第 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>"
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
步骤 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>"
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.
生成此密钥库后,将其保存在应用程序的原始文件夹中。使用以下代码与 openfire 服务器进行证书握手。
To create a connection with openfire using XMPP, you may need to get the config. For the same, use the below method:
要使用 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; }
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
在我的博客smackssl.blogspot.in 中都遵循相同的内容
回答by deeringc
Yes, it's quite easy to achieve. Take a look at the ConnectionConfigurationclass, and in particular the setSecurityMode method which accepts a ConnectionConfiguration.SecurityMode enum as a parameter. Setting this to "required" forces Smack to use TLS.
是的,这很容易实现。看看ConnectionConfiguration类,特别是 setSecurityMode 方法,它接受 ConnectionConfiguration.SecurityMode 枚举作为参数。将此设置为“必需”会强制 Smack 使用 TLS。
from the Javadoc:
来自 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.
连接时需要通过 TLS 加密确保安全。如果服务器不提供 TLS 或 TLS 协商失败,则与服务器的连接将失败。

