连接到XMPP服务器时,Smack中的TLS

时间:2016-07-12 23:04:18

标签: android sockets ssl xmpp smack

我正在尝试连接到Firebase云消息传递CCS。我正在使用Smack,需要建立一个安全的TLS连接,然后通过SASLMechanism“Plain”进行身份验证。我已经对这个主题进行了大量的阅读,并发现首先必须建立TLS,然后使用“普通”SASLMechanism进行身份验证。我有点卡在TLS部分。我用java keytool创建了一个“csr” - 证书签名请求。 “csr”已成功通过GeoTrust.com签署,但我必须先以我的名义注册域名才能获得此签名证书。所以,我猜这个证书是为我的域名验证的,但是我试图用它来建立与“FCM”的TLS连接。证书附带两个中间证书。三个证书中的每一个都已保存在我的Assets文件夹下作为Android Studio中的文本文件。证书在我的Android代码中正确上传,但是我已经读过使用BufferedReader更好。以下是我上传证书的方式:

try {
input = manager.open("certi");
input1 = manager.open("certii");
input2 = manager.open("certiii");
InputStream caInput = new BufferedInputStream(input);
InputStream stream1 = new BufferedInputStream(input1);
InputStream stream2 = new BufferedInputStream(input2);
Certificate ca,ca1, ca2;
try {
cf = CertificateFactory.getInstance("X.509");
cf1 = CertificateFactory.getInstance("X.509");
cf2 = CertificateFactory.getInstance("X.509");
ca = cf.generateCertificate(caInput);
ca1 = cf1.generateCertificate(stream1);
ca2 = cf2.generateCertificate(stream2);
InterfaceClass.certificate = ca;
InterfaceClass.inter_certificate1 = ca1;
InterfaceClass.inter_certificate2 = ca2;

现在,根据我的阅读,最好加载这样的证书:

InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));  //NOTICE THE FILEINPUTSTREAM USED I USE INPUTSTREAM
//INPUT,INPUT1,INPUT2

我还为这三个证书中的每一个创建了一个密钥库:

//I do this three times cause each keystore will have one different
//certificate   
String keyStoreType = KeyStore.getDefaultType();
try {
keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", InterfaceClass.certificate);

//creating a trustmanagerfactory
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = null;
try {
tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
//initializing the keystore with the tmf
try {
tmf.init(keyStore); //do this three times for keystore1, keystore2
TrustManager[] trust = tmf.getTrustManagers();
int size = trust.length;
Log.d("trusti","first: "+size);// i expect to get size = 3 but size =1 WHY?
//CREATING AN SSLCONTEXT FOR MY SMACK CONFIGURATIONBUILDER OBJECT
SSLContext context = null;
try {
context = SSLContext.getInstance("TLS");

现在从上面的代码中,为什么size = 1,我认为它是3,因为我初始化了三个不同的密钥库,它们拥有三个不同的证书? 也许这就是我得到以下异常的原因: javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:找不到证书路径的信任锚。

我认为我的smack连接的configurationbuilder对象没有获得使用“FCM”建立TLS所需的所有三个证书。我怎样才能做到这一点?我尝试用三个不同的证书创建一个密钥库,但是没有用。我尝试在同一个Assets文本文件中复制并粘贴所有三个证书,并使用该文本文件和一个密钥库创建一个证书,它也没有用。如何在我的trustmanagerfactory对象中获得更多信任管理器?

另外,我应该如何在我的连接中使用这个SSlcontext对象:这是我尝试过的方式,哪种方式最好:

//way 1
configBuilder.setCustomSSLContext(context);
//way 2
configBuilder.setSocketFactory(context.getSocketFactory());

我收到的错误提供了有用的信息,错误如下:at org.jivesoftware.smack.tcp.XMPPTCPConnection.initReaderAndWriter(XMPPTCPConnection.java:655)当我在第655行上线时它把我带到了Smack的内部方法调用之一。这告诉我,不知何故输入流没有在套接字中读取。我想套接字无法读取具有我所有三个证书的输入流,这就是我无法建立信任锚验证路径的原因。这是Smack的内部方法调用的样子:

private void initReaderAndWriter() throws IOException {
InputStream is = socket.getInputStream(); //ERROR THROWN HERE

我的SSlcontext对象是否与此套接字通信。如何在代码中访问此套接字以使其找到我的信任证书?

此外,我的连接的最佳设置是什么:我已经尝试了两种,但仍然会出错:

//way1
configBuilder.setSecurityMode(XMPPTCPConnectionConfiguration.SecurityMode.required);
configBuilder.setServiceName("fcm-xmpp.googleapis.com");
configBuilder.setHost("fcm-xmpp.googleapis.com"); 
configBuilder.setPort(5236);
configBuilder.setCompressionEnabled(false); 
configBuilder.setSendPresence(false);/SHOULD THIS BE TRUE
configBuilder.setUsernameAndPassword("senderID"+"@gcm.googleapis.com",      serverKey);
XMPPTCPConnection.setUseStreamManagementDefault(true); //WHAT IS THIS FOR
XMPPTCPConnection.setUseStreamManagementResumptionDefault(true);//???
FCMconnection = new   XMPPTCPConnection(TLSUtils.setTLSOnly(configBuilder).build());//NOTICE HERE

//way2: everything same as way1 but these two lines:
configBuilder.setSecurityMode(XMPPTCPConnectionConfiguration.SecurityMode.disabled);
FCMconnection = new XMPPTCPConnection(configBuilder.build()); 

请帮我整理这些东西。在此之后,我将不得不使用“FCM”处理Smack上的SASLMechanism认证。希望比TLS更顺利。再次,任何adivce或建议非常感谢。

0 个答案:

没有答案