How to connect to a server with a self signed certificate from android using 5222 port

Put your certificate into the asset folder (***.crt). Just download it using Firefox when you enter your domain via https

then use the following code

XMPPTCPConnectionConfiguration   config  = XMPPTCPConnectionConfiguration.builder()

.setHost(HOST)

.setPort(PORT) // default 5222

.setServiceName(SERVECE_NAME) // usually the same as your server name

.setCustomSSLContext(getSSLContext())

.setResource(RESOURCE)

        .setUsernameAndPassword(USERNAME, PASSWORD)

.setCompressionEnabled(true)

.setSecurityMode(ConnectionConfiguration.SecurityMode.required)

.setDebuggerEnabled(true)

.setSendPresence(false).build();

.

.

.

public  SSLContext getSSLContext (){

CertificateFactory cf = null;

SSLContext context= null;

try {

cf = CertificateFactory.getInstance("X.509");

InputStream caInput = new BufferedInputStream((application or activity Context).getAssets().open("***.crt"));

Certificate ca = cf.generateCertificate(caInput);

String keyStoreType = KeyStore.getDefaultType();

KeyStore keyStore = KeyStore.getInstance(keyStoreType);

keyStore.load(null, null);

keyStore.setCertificateEntry("ca", ca);

String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();

TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);

tmf.init(keyStore);

// Create an SSLContext that uses our TrustManager
            context = SSLContext.getInstance("TLS");

context.init(null, tmf.getTrustManagers(), null);

} catch (CertificateException e) {

e.printStackTrace();

} catch (KeyManagementException e) {

e.printStackTrace();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (KeyStoreException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return context;

}

Resources: CertificateFactory (Java Platform SE 7 )

As possible easier-to-use alternative, I recommend using Java Pinning: https://github.com/flowdalic/java-pinning

Instead of the above, pinning a certificate with Java Pinning and Smack comes down to

SSLContext sc = JavaPinning
  .forPin("SHA256:e3b1812d945da1a2a2c5fa28029d2fe34c7c4142fb098f5cfedff1ff20e98781");

XMPPTCPConnectionConfiguration conf = XMPPTCPConnectionConfiguration.builder()
  .setUsernameAndPassword("user", "pass")
  .setService("example.org")
  .setCustomSSLContext(sc)
  .build();
1 Like

For me I would use JavaPinning but for some reasons smack throw exception so that I used that way.

E/XMPPManager﹕ XMPP connection failed org.jivesoftware.smack.SmackException: javax.net.ssl.SSLHandshakeException: Certificate not pinned

Most likely your PIN String was wrong. Newer versions of Java Pinning will tell you in the exception message what would be the correct PIN String for the certificate currently seen. Note that you still need to verify the PIN String, if it’s the expected value as otherwise you may been MitM’ed.

Yes you are right I’m using an old jar of java Pinning. I will give it a try again, thank you.