2015-12-11 46 views
2

我正在使用Netty 4.0.30 我已經在仿真器和運行Android 4.4.4的設備上測試過我的代碼,但是我沒有看到此問題。在這些情況下一切正常。Netty 4解碼器錯誤與SSL

在運行Android 5.02的我的HTC One上,每次在我的SSL連接期間都會發生這種情況。我是SSL的總諾貝爾,我的代碼幾乎沒有從netty(https://github.com/netty/netty/tree/4.0/example/src/main/java/io/netty/example/securechat)提供的SSL聊天示例修改。

服務器端看到「SSL通道活動」和「SSL操作完成調用」,但不會打印任何其他錯誤或其他錯誤。客戶端看到「SSL通道活動,發送:無效」,然後出錯。基本上沒有一方似乎讀取成功。這裏是堆棧跟蹤,從客戶端:

W/System.err: io.netty.handler.codec.DecoderException: javax.net.ssl.SSLException: javax.net.ssl.SSLProtocolException: Read error: ssl=0xb8c20ae0: Failure in SSL library, usually a protocol error 
W/System.err: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac (external/openssl/ssl/s3_pkt.c:485 0xb150b0dd:0x00000000) 
W/System.err:  at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:358) 
W/System.err:  at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:230) 
W/System.err:  at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308) 
W/System.err:  at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294) 
W/System.err:  at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846) 
W/System.err:  at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131) 
W/System.err:  at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511) 
W/System.err:  at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:430) 
W/System.err:  at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:384) 
W/System.err:  at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354) 
W/System.err:  at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:110) 
W/System.err:  at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137) 
W/System.err:  at java.lang.Thread.run(Thread.java:818) 
W/System.err: Caused by: javax.net.ssl.SSLException: javax.net.ssl.SSLProtocolException: Read error: ssl=0xb8c20ae0: Failure in SSL library, usually a protocol error 
W/System.err: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac (external/openssl/ssl/s3_pkt.c:485 0xb150b0dd:0x00000000) 
W/System.err:  at com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:491) 
W/System.err:  at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:1006) 
W/System.err:  at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1129) 
W/System.err:  at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1019) 
W/System.err:  at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:959) 
W/System.err:  at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:327) 
W/System.err: ... 12 more 
W/System.err: Caused by: javax.net.ssl.SSLProtocolException: Read error: ssl=0xb8c20ae0: Failure in SSL library, usually a protocol error 
W/System.err: error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac (external/openssl/ssl/s3_pkt.c:485 0xb150b0dd:0x00000000) 
W/System.err:  at com.android.org.conscrypt.NativeCrypto.SSL_read_BIO(Native Method) 
W/System.err:  at com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:472) 
W/System.err: ... 17 more 

下面是我的代碼片段,但實際上他們是從例子中,客戶端幾乎沒有不同:

 // Configure SSL. 
    EventLoopGroup group = new NioEventLoopGroup(); 
    try { 
     final SslContext sslCtx = SslContextBuilder.forClient() 
       .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); 

     Bootstrap b = new Bootstrap(); 
     b.group(group) 
       .channel(NioSocketChannel.class) 
       .handler(new SSLClientInitializer(sslCtx,server,port)); 

     // Start the connection attempt. 
     Channel ch = b.connect(server, port).sync().channel(); 

     // Wait until the connection is closed. 
     ch.closeFuture().sync(); 
     System.out.println("SSL closed"); 

初始化程序:

@Override 
public void initChannel(SocketChannel ch) throws Exception { 
    ChannelPipeline pipeline = ch.pipeline(); 

    // Add SSL handler first to encrypt and decrypt everything. 
    // In this example, we use a bogus certificate in the server side 
    // and accept any invalid certificates in the client side. 
    // You will need something more complicated to identify both 
    // and server in the real world. 
    pipeline.addLast(sslCtx.newHandler(ch.alloc(), server, port)); 

    // On top of the SSL handler, add the text line codec. 
    pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); 
    pipeline.addLast(new StringDecoder()); 
    pipeline.addLast(new StringEncoder()); 

    // and then business logic. 
    pipeline.addLast(new SSLClientHandler()); 
} 

處理程序:

​​

服務器:

EventLoopGroup bossGroup = new NioEventLoopGroup(1); 
    EventLoopGroup workerGroup = new NioEventLoopGroup(); 
    try { 
     SelfSignedCertificate ssc = new SelfSignedCertificate();//@todo need a real cert 
     SslContext sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()) 
       .build(); 

     ServerBootstrap b = new ServerBootstrap(); 
     b.group(bossGroup, workerGroup) 
       .channel(NioServerSocketChannel.class) 
       //.handler(new LoggingHandler(LogLevel.INFO)) 
       .childHandler(new SSLServerInitializer(sslCtx)); 

     b.bind(port).sync().channel().closeFuture().sync(); 

初始化程序:

@Override 
public void initChannel(SocketChannel ch) throws Exception { 
    ChannelPipeline pipeline = ch.pipeline(); 

    // Add SSL handler first to encrypt and decrypt everything. 
    // In this example, we use a bogus certificate in the server side 
    // and accept any invalid certificates in the client side. 
    // You will need something more complicated to identify both 
    // and server in the real world. 
    pipeline.addLast(sslCtx.newHandler(ch.alloc())); 

    // On top of the SSL handler, add the text line codec. 
    pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); 
    pipeline.addLast(new StringDecoder()); 
    pipeline.addLast(new StringEncoder()); 

    // and then business logic. 
    pipeline.addLast(new SSLServerHandler()); 
} 

處理程序:

@Override 
public void channelActive(final ChannelHandlerContext ctx) { 
    // Once session is secured, send a greeting and register the channel to the global channel 
    // list so the channel received the messages from others. 
    System.out.println("SSL channel active"); 
    ctx.pipeline().get(SslHandler.class).handshakeFuture().addListener(
      new GenericFutureListener<Future<Channel>>() { 
       @Override 
       public void operationComplete(Future<Channel> future) throws Exception { 
        System.out.println("SSL Operate Complete called"); 
        ctx.writeAndFlush("Your session is protected by " + 
            ctx.pipeline().get(SslHandler.class).engine().getSession().getCipherSuite() + 
            " cipher suite.\n"); 

        channels.add(ctx.channel()); 
       } 
      }); 
} 

@Override 
public void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { 
    System.out.println("SSL read0:" + msg); 
    ctx.writeAndFlush("granted\n"); 

    ctx.close(); 

} 

任何幫助表示讚賞,我看到了這一點,我擔心它與/不固定:https://github.com/netty/netty/issues/4116 謝謝讀!

更新 此行爲是一致的仿真器,以及,連接工作正常奇巧而不是針對Android> 5.0。我注意到我的(連接工作)4.4.4設備僅支持TLSv1和SSLv3,其中(非工作連接)設備支持TLSv1.2,我相信使用此版本的協議

+0

之所以能夠在另一部手機上測試這個,LG G2運行Android 5.02,與我的HTC一樣。這款手機也出現了同樣的錯誤。尋找工作。 – M1LKYW4Y

回答

0

雖然不理想,目前的一項工作是使用較早版本的Netty 4.0.25,然後填寫SslContextBuilder的差距,因爲它在此版本中不存在。客戶端已在4.0.30改變來自:

final SslContext sslCtx = SslContextBuilder.forClient() 
       .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); 

這個在4.0.25:

final SslContext sslCtx; 
     TrustManagerFactory trustManagerFactory = InsecureTrustManagerFactory.INSTANCE; 
     SslProvider provider = SslContext.defaultClientProvider(); 
     File trustCertChainFile = null; 
     File keyCertChainFile = null; 
     File keyFile = null; 
     String keyPassword = null; 
     KeyManagerFactory keyManagerFactory = null; 
     Iterable<String> ciphers = null; 
     ApplicationProtocolConfig apn = null; 
     switch (provider) { 
      case JDK: 
       sslCtx = new JdkSslClientContext(
         trustCertChainFile, trustManagerFactory, keyCertChainFile, keyFile, keyPassword, 
         keyManagerFactory, ciphers, IdentityCipherSuiteFilter.INSTANCE, apn, 0, 0); 
       break; 
      case OPENSSL: 
      default: 
       sslCtx = new OpenSslClientContext(
         trustCertChainFile, trustManagerFactory, 
         ciphers, apn, 0, 0); 
       break; 
     } 

編輯#2 否認編輯#1