本文介绍的是如何使用自签名证书来建立与Tigase的连接
解压后可以看到certs目录下有四个keystore之类的文件,这是tigase默认提供的自签证书相关的文件,它们的作用是自动创建虚拟域的证书。
此时我已成功导入并运行了tigase服务,设置了一个虚拟域:songguoim
此时使用Psi客户端进行连接:
你会看到这样的提示,点击详细资料
可以看到这个证书是Tigase自己生成的,我们只需要选择“相信这个凭证”,就可以正常连接,之后不会再弹出证书无效的提示,选择“仍是连接”表明本次信任该证书,下次连接还会弹出提示。
当你连接上Psi之后,此时我们回到certs目录,会发现多出两个文件:
default.pem和songguoim.pem,其中songguoim对应我配置的虚拟域,同理,如果配置了多个虚拟域,则会生成多个pem文件。打开songguoim.pem文件
会发现它是由证书和私钥组成,而且格式是压缩的,而如果我们要用smack或者jaxmpp在代码里进行连接呢?
1、删除其他pem文件,留下默认的那4个文件
2、我已经安装好了openssl并将openssl加入到path环境变量里,也将jdk的环境变量设置好。
3、生成tigase所需的域证书:songguoim.pem
进入你要存放证书的目录下,输入openssl并回车,再输入命令:
req -nodes -new -newkey rsa:2048 -keyout songguoim.key -out songguoim.csr
提示:songguoim是我自己设置的虚拟域,您可以更改为自己的
接着输入命令:
x509 -req -days 365 -in songguoim.csr -signkey songguoim.key -out songguoim.crt
接着创建一个txt文件改名songguoim.pem,将上面的crt文件内容拷贝进去,再把key文件内容拷贝进去,大致内容如下:
-----BEGIN CERTIFICATE-----
MIIDoTCCAokCFF9wD38Kut0uQYJXnnsA//BC6BsUMA0GCSqGSIb3DQEBCwUAMIGM
7X+f26u+PhhhPtGGVZE1oFLnwNMp
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDoKZb1wRQYpxbw
g9t3nBMFztgdipHzscR7bBB+
-----END PRIVATE KEY----
4、生成客户端所需的keystore
在上节的命令行里继续输入命令:
pkcs12 -export
-in
songguoim.crt -inkey songguoim.key -out songguoim.p12
需要输入密码,代码里要用到
接着ctrl+c退出openssl命令,输入命令:
keytool -importkeystore -v
-srckeystore songguoim.p12 -srcstoretype pkcs12 -srcstorepass 你设置的密码 -destkeystore songguoim.keystore -deststoretype jks -deststorepass 你设置的密码
5、将songguoim.pem文件复制到tigase的certs文件夹中,接着启动tigase
6、将songguoim.keystore复制到项目目录,大致结构如图:
7、客户端使用smack编写代码测试连接:
import org.jivesoftware.smack.ConnectionConfiguration; import org.jivesoftware.smack.tcp.XMPPTCPConnection; import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import java.security.KeyStore; import java.security.cert.X509Certificate; /** * 连接tigase服务器有三种方式 * * 纯文本 * starttls * tls/ssl * * 第二种是纯文本的扩展协议,如果双方都支持加密,则可将纯文本传输升级为加密传输,加密传输和非加密 */ public class XMPPConnectionFactory { public static void main(String[] args) { try{ //使用STARTTLS连接 SSLContext ctx = SSLContext.getInstance("SSL"); TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509"); KeyStore tks = KeyStore.getInstance("JKS"); tks.load(XMPPConnectionFactory.class.getResourceAsStream("/songguoim.keystore"), "您设置的密码".toCharArray()); tmf.init(tks); ctx.init(null, tmf.getTrustManagers(), null); XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder() .setHost("192.168.0.190")//本机ip .setXmppDomain("songguoim")//虚拟域 .setPort(5222)//tigase端口 .setSslContextFactory(() -> ctx) .setSecurityMode(ConnectionConfiguration.SecurityMode.required) .setResource("Smack") //信任自签证书,关键 .setCustomX509TrustManager(new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } }) .build(); XMPPTCPConnection connection=new XMPPTCPConnection(config); connection.connect(); try { connection.login("junko1@songguoim", "junko2013");//这是我之前通过Psi客户端创建的账号和密码,需要替换成您自己的 System.out.println("登陆成功"); }catch (Exception e){ System.out.println("登录失败"); e.printStackTrace(); } }catch (Exception e){ e.printStackTrace(); } } }
如果还有什么不懂的可以留下评论,我会第一时间作答。