Android開發使用Netty的TCP串連中使用SSL加密

來源:互聯網
上載者:User

 

1 Introduction
 
資料安全在網路通訊中是非常重要的一個方面。為了支援 SSL/TLS,Java 提供了 javax.net.ssl包下的類SslContext 和 SslEngine 。在Netty架構下,I/O資料在ChannelPipeline中被管道中的ChannelHandler處理並轉寄給下一個ChannelHandler。自然而然地,Netty也提供了ChannelHandler的實現SslHandler來支援SSL, 有一個內部 SslEngine 做實際的工作。
 
2 Steps
 
首先看看SslHandler的建構函式:
   public SslHandler(SSLEngine engine) {
        this(engine, false);
    }

    public SslHandler(SSLEngine engine, boolean startTls) {
        this(engine, startTls, ImmediateExecutor.INSTANCE);
    }
不難發現,我們需要一個SSLEngine對象來構建SslHandler。根據資料可以知道,需要根據已初始化的 SSLContext 來調用 SSLContext.createSSLEngine() 即可建立 SSLEngine。
所以基於Netty架構的在TCP串連中使用SSL/TLS加密的流程如下:
 1.在代碼中匯入認證,並使用該認證構造SSLContext
2.調用SSLContext對象的createSSLEngine()建立 SSLEngine
3.用SSLEngine對象去初始化Netty的SslHandler
4.在Netty的ChannelInitializer.initChannel()中,往管道(pipeline)中安裝SslHandler。
 
3 Usage
 
3.1 匯入認證
 public SSLContext getClientSSLContext(){
  KeyStore trustKeyStore= KeyStore.getInstance("JKS");// 訪問Java密鑰庫,JKS是keytool建立的Java密鑰庫
  InputStream keyStream = MyApplication.getAppContext().getAssets().open("key.jks");//開啟認證檔案(.jks格式)
  char keyStorePass[]="12345678".toCharArray();  //認證密碼
  keyStore .load(trustKeyStore,keyStorePass);


  TrustManagerFactory trustManagerFactory =   TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore );//儲存服務端的授權認證

SSLContext   clientContext = SSLContext.getInstance( "TLS");
  clientContext.init(null, trustManagerFactory.getTrustManagers(), null);

  return clientContext;
}
在上述代碼,只是實現了client採用trustKeyStore中的key.jks認證(包含了server的公開金鑰)對資料解密,如果解密成功,證明訊息來自server,進行邏輯處理。
僅僅是server->client單向的SSL認證。
如果要實現server和client之間雙向的身份認證,需要模仿trustManagerFactory的初始化來構建一個KeyManagerFactory來其中儲存用戶端的私密金鑰,並傳入
clientContext.init(kmf.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

具體參照 SSL雙向認證java實現
 
3.2 添加 SslHandler
 
ChannelHandler在應該初始化(ChannelInitializer.initChannel()被調用時)階段被安裝在ChannelPipeline中。
 

Bootstrap的介紹參考Android開發之使用Netty進行Socket編程(二)
Boostrap的初始化參考Android開發之使用Netty進行Socket編程(三)
   bootstrap.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();
                SSLEngine engine = getClientSSLContext().createSSLEngine();
                engine.setUseClientMode(true);
                pipeline.addFirst("ssl", new SslHandler(engine));

                //....再添加其他的ChannelHandler
                pipeline.addLast(nettyChannelHandler);
            }
        });
在大多數情況下,SslHandler 將成為 ChannelPipeline 中的第一個 ChannelHandler,所以調用了pipeline.addFirst() 。這將確保所有其他 ChannelHandler 應用他們的邏輯到資料後加密後才發生,從而確保他們的變化是安全的

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.