简体   繁体   中英

Using ssl with Apache Mina & android

I am trying to use Mina with android. Up to this everything is working fine. Now I am trying to add SSL support using SSLFilter dynamically. My problem is on device, I am getting 'isSSLStarted' 'true' but when I send message, my connection is get closed. Can anybody help me to analyze & solve this issue? Is this due to handshake failure? How to check if handshake is successfull or not.

Some more details. I am using JSON communication.

SSLContext c = SSLContext.getInstance( "TLS" );
c.init(null, null, null);          
 SslFilter sslFilter = new SslFilter(c);
sslFilter.setUseClientMode(true);
session.getFilterChain().addFirst("mySSL", sslFilter);
session.setAttribute(SslFilter.DISABLE_ENCRYPTION_ONCE, Boolean.TRUE);
--sending msg in JSON
assert session.getAttribute(SslFilter.DISABLE_ENCRYPTION_ONCE) == null;
Log.v(TAG,"isSslStarted:"+sslFilter.isSslStarted(session)); 

==> it gives true.

Thanks in advance.

I got following issues when I try to connect using plain java.

javax.net.ssl.SSLHandshakeException: SSL handshake failed.
    at org.apache.mina.filter.ssl.SslFilter.messageReceived(SslFilter.java:487)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:417)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1200(DefaultIoFilterChain.java:47)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:765)
    at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapter.java:109)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:417)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain.fireMessageReceived(DefaultIoFilterChain.java:410)
    at org.apache.mina.core.polling.AbstractPollingIoProcessor.read(AbstractPollingIoProcessor.java:710)
    at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:664)
    at org.apache.mina.core.polling.AbstractPollingIoProcessor.process(AbstractPollingIoProcessor.java:653)
    at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$600(AbstractPollingIoProcessor.java:67)
    at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:1124)
    at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

Caused by: javax.net.ssl.SSLException: Received fatal alert: protocol_version
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
    at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1619)
    at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1587)
    at sun.security.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1756)
    at sun.security.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:1060)
    at sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:884)
    at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:758)
    at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
    at org.apache.mina.filter.ssl.SslHandler.unwrap(SslHandler.java:728)
    at org.apache.mina.filter.ssl.SslHandler.unwrapHandshake(SslHandler.java:666)
    at org.apache.mina.filter.ssl.SslHandler.handshake(SslHandler.java:552)
    at org.apache.mina.filter.ssl.SslHandler.messageReceived(SslHandler.java:351)
    at org.apache.mina.filter.ssl.SslFilter.messageReceived(SslFilter.java:468)

isSSLStarted flag will be removed when a "write" method is called... You can go through this link:

http://mina.apache.org/mina-project/apidocs/org/apache/mina/filter/ssl/SslFilter.html?_sm_au_=iNMNsvHrtNLTFqfF#DISABLE_ENCRYPTION_ONCE

Finally I am able to do successfully handshake using plain java. My implementation is something like following.

public void startTLS() {

    try {
        sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustCerts, null);
    } catch(NoSuchAlgorithmException nsa) {
        System.out.println("Exception : No Such Algorithm");
    } catch(KeyManagementException kme) {
        System.out.println("Exception : KeyManagementException:");
    }//try-catch


    IoFilterChain chain = session.getFilterChain();
    SslFilter sslFilter = (SslFilter) chain.get("sslFilter");

    if (sslFilter == null) {
        sslFilter = new SslFilter(sslContext);
        sslFilter.setUseClientMode(true);
        if ((cipherSuites != null) && !cipherSuites.isEmpty()) {
            sslFilter.setEnabledCipherSuites(cipherSuites.toArray( new String[cipherSuites.size()] )); 
        } 

        chain.addFirst("sslFilter", sslFilter);

    }else {
        try {
            sslFilter.startSsl(this.session);
        } catch(SSLException se) {
            System.out.println("SslException:"+se);
        }
    }//if-else

}//startTLS

But it failed with Android. It looks like this is an old known issue.

http://code.google.com/p/android/issues/detail?id=4914

https://issues.apache.org/jira/browse/DIRMINA-972

Please let me know if I am making any mistakes.

Thank You.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM