<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jack Jiang

    我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
    posts - 494, comments - 13, trackbacks - 0, articles - 1

    1、引言

    對于IM聊天應用來說,為了提升安全性,對聊天消息加密是常規操作。

    眾所周之,Netty是高性能的Java NIO網絡通信框架,因而用Netty來寫IM是再正常不過了。網上關于為Netty生成、以及使用SSL/TLS證書的文章有很多,但由于各種原因,生成的證書要么是Netty中無法讀取和使用,要么是代碼不全或不具體導致根本配不通SSL/TLS加密。

    正好這段時間專門為 MobileIMSDK 生成了一套測試證書,順手把這個過程記錄了下來,分享給大家。

    本文要分享的是如何使用OpenSSL生成在基于Netty的IM中真正可用的SSL/TLS證書,內容包括:證書的創建、創建過程中的注意點,以及在Server端、Android端、iOS端、Java桌面端、H5端使用證書的代碼范例。

    注:對于那些付費購買了第3方權威CA機構簽發的證書,他們都有相應的使用文檔,這就沒什么好說的。本文里的證書指的是不需要花錢的自簽名證書。

    學習交流:

    (本文已同步發布于:http://www.52im.net/thread-4142-1-1.html

    2、知識準備

    ► 如果你對IM系統毫無概念,建議先閱讀《零基礎IM開發入門(一):什么是IM系統?》系列文章,通俗易懂,適合小白。

    ► 如果你想系統學習IM開發相關的理論知識,比如網格編程、IM架構設計等,建議先閱讀《新手入門一篇就夠:從零開發移動端IM》。

    ► 如果你不了解Netty是什么,建議閱讀以下幾篇Netty的基礎入門好文章:

    ► 如果你已掌握IM理論知識,同時也對Netty基本掌握,正準備動手實戰,則可以閱讀《基于Netty,從零開發IM》和《跟著源碼學IM》這個系列文章,有各種入門級實戰代碼,圖文并茂,適合學習。

    ► 如果你對IM、Netty已基本上手,但對IM安全方面的技術概念有點理不清,建議必讀《基于Netty的IM聊天加密技術學習:一文理清常見的加密概念、術語等》。

    3、什么是Netty

    Netty是一個Java NIO技術的開源異步事件驅動的網絡編程框架,用于快速開發可維護的高性能協議服務器和客戶端。往通俗了講,可以將Netty理解為:一個將Java NIO進行了大量封裝,并大大降低Java NIO使用難度和上手門檻的超牛逼框架。(引用自《史上最通俗Netty框架入門長文:基本介紹、環境搭建、動手實戰》)

    PS:限于篇幅,對于Netty方面的入門知識就不再贅述,如有必要,請仔細跟著本文第二節“2、知識準備”里有關Netty的文章進行閱讀。

    4、什么是OpenSSL

    OpenSSL是一個開放源代碼的軟件庫,應用程序可以使用這個包來進行安全通信,它包括代碼、腳本、配置和過程的集合。其主要庫是以 C 語言所寫成,實現了基本的加密功能,實現了 SSL 與 TLS 協議。OpenSSL整個軟件包大概可以分成三個主要功能部分:SSL協議庫、應用程序、密碼算法庫。

    PS:OpenSSL的介紹就點到為止,如有興趣,可仔細閱讀《基于Netty的IM聊天加密技術學習:一文理清常見的加密概念、術語等》。

    5、下載和安裝OpenSSL

    1)方法一:可以從OpenSSL的Github倉庫下載源碼自行編譯(源碼下載地址),對于一般使用者來說,自已編譯著實有點麻煩,不推薦這么玩。

    2)方法一:也可以從這個網站下載第3方編譯好的OpenSSL安裝程序(安裝程序下載地址),這樣上手簡單快捷。具體可以參考《openssl安裝教程(windows7系統,超詳細)》這篇文章。

    3)方法一:也可以直接用下面附件里的安裝程序(這是我一直用的版本,版本較老,有興趣可直接下載使用):

     Openssl-windows-0.9.8k(52im.net).rar (874.97 KB , 下載次數: 1 , 售價: 1 金幣)

    4)解決 “openssl.cnf找不到” 的問題:如果你安裝好OpenSSL后,使用時報“openssl.cnf找不到”或“計算機缺少openssl.cnf”等之類錯誤提示,可以下載下面這個 openssl.cnf文件。

    openssl.cnf 文件附件下載:

     openssl_conf(52im.net).rar (4.63 KB , 下載次數: 1 , 售價: 1 金幣)

    openssl.cnf 文件解壓縮后:

    openssl.cnf文件配置使用:

    以下是 openssl.cnf 文件的配置使用命令:(以我的安裝目錄為例)

    C:\Openssl-windows-0.9.8k-out32dll>set OPENSSL_CONF=c:/WINDOWS/system32/openssl.cnf

    準備就緒,接下來我們就可以開始生成SSL/TLS證書了!

    6、生成Netty可用的SSL/TLS證書

    6.1概述

    經過實踐,生成Netty可用的SSL/TLS證書需要4步:

    • 1)創建私鑰證書;
    • 2)將私鑰格式轉成pk8;
    • 3)創建證書請求;
    • 4)生成公鑰證書。

    接下來,跟著本節內容,一步步使用OpenSSL生成一個真正能在Netty中能使用的自簽名證書。

    6.2第一步:創建私鑰證書

    在CMD控制臺下執行如下指令:(記得手動創建 netty 目錄)

    openssl genrsa -des3 -out netty/netty-key.pem 1024

    提示:以上指令中,如無“-des3”參數,則Netty的代碼中使用時將報“File does not contain valid private key”等錯誤(如下圖所示)。

    6.3第二步:將私鑰格式轉成pk8

    在CMD控制臺下執行如下指令:

    openssl pkcs8 -innetty/netty-key2.pem -topk8 -out netty/netty-key2.pk8

    提示1:如不轉pk8格式,則Netty的代碼中使用時會報以下錯誤:

    提示2:如代碼中不為key加入密碼,則Netty的代碼中使用時會報以下錯誤:

    提示3:Netty的代碼中使用時要加入上方生成Key證書時的密碼即可:

    6.4第三步:創建證書請求

    在CMD控制臺下執行如下指令:

    openssl req -new -out netty/netty-req2.csr -key netty/netty-key2.pem

    提示:經上指令中,Common Name指明的是證書綁定的域名,你可以用域名或ip,本次生成用了子域名。

    6.5第四步:生成公鑰證書

    在CMD控制臺下執行如下指令:

    openssl x509 -req -inca/ca-req2.csr -out netty/netty-cert2.crt -signkey netty/netty-key2.pem -days 3650

    提示:out 參數生成的是.crt,而在前面的是.pem,這只是擴展名區別,內容都一樣。

    6.6最終成果

     

    至此,我們已經為Netty創建好了證書,接下來的章節,就是分享如何讀取和使用這些證書的。

    7、實戰代碼

    7.1概述

    本節將為你演示如何在基于Netty的IM中使用上節中生成的證書。

    為了讓示例代碼更具實戰意義,本節的示例代碼將引用的是開源IM框架MobileIMSDK  的源碼,如果有興趣深入學習,可以從下面的開源倉庫中下載到MobileIMSDK的完整源碼。

    7.2基于Netty的IM服務端如何開啟SSL/TLS

    首先將上節中生成的證書,放置到你的IM服務端磁盤目錄下。以下截圖和示例代碼以MobileIMSDK的開源代碼為例。

    我們可以將證書放到這個位置:

    使用證書的示例代碼片段:完整代碼詳見 ServerLauncherImpl.java

    /**

     * 創建SslContext對象,用于開啟SSL/TLS加密傳輸。

     *

     * @return 如果成功創建則返回SslContext對象,否則返回null

     */

    privatestaticSslContext createSslContext() {               

        try{

             // 證書文件

             InputStream certChainFile = ServerLauncherImpl.class.getResourceAsStream("certs/netty-cert2.crt");

             // 私鑰文件(注意:Netty只支持.pk8格式)

             InputStream keyFile = ServerLauncherImpl.class.getResourceAsStream("certs/netty-key2.pk8");

             // 私鑰密碼

             String keyPassword = "123456";

             // 生成SslContext對象(為了方便理解,此處使用的是單向認證)

             SslContext sslCtx = SslContextBuilder.forServer(certChainFile, keyFile, keyPassword).clientAuth(ClientAuth.NONE).build();                 

             returnsslCtx;

        } catch(Exception e) {

            logger.warn("createSslContext()時出錯了,原因:"+e.getMessage(), e);

        }

        returnnull;

    }

    PS:如果你想自已動手完整運行一下,可以閱讀《MobileIMSDK的Demo使用幫助:Server端》。

    接下來的內容,我們將實現客戶端連接到使用SSL/TLS證書的Netty IM服務端。

    7.3Android端如何開啟SSL/TLS

    因為服務端已經開啟了SSL/TLS加密,我們在開發IM的客戶端時,該如何啟用SSL/TLS呢(否則你未開啟SSL/TLS的客戶端肯定是連不上你的服務端的)?

    這里為了方便示例,我們同樣以 MobileIMSDK的Android端開源代碼為例。

    Android端開啟SSL/TLS加密的示例代碼片段:(完整代碼詳見 IMClientManager.java

    /**

     * 創建SslContext對象,用于開啟SSL/TLS加密傳輸。

     *

     * @return 如果成功創建則返回SslContext對象,否則返回null

     */

    publicSslContext createSslContext() {

            SslContext sslContext = null;

            try{

                    sslContext = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();

                    Log.d(TAG, "【IMCORE-TCP】已開啟SSL/TLS加密(單向認證),且sslContext創建成功。");

            } catch(Exception e) {

                    Log.w(TAG, "【IMCORE-TCP】創建sslContext時出錯,原因是:"+ e.getMessage(), e);

            }

     

            returnsslContext;

    }

    PS:如果你想自已動手完整運行一下,可以閱讀《MobileIMSDK的Demo使用幫助:Android版》。

    7.4iOS端如何開啟SSL/TLS

    同樣的,iOS端該如何開啟SSL/TLS呢?

    這里我們依然以 MobileIMSDK的iOS端開源代碼為例(MobileIMSDK的iOS使用的是 CocoaAsyncSocket 網絡庫,如果你也是用的它,就可以直接參考了,因為開啟了SSL/TLS的CocoaAsyncSocket代碼跟未開啟加密的代碼用法差異較多,且這方面可以參考的資料較少)。

    iOS端開啟SSL/TLS加密的示例代碼片段:(完整代碼詳見 LocalSocketProvider.m

    /**

     * 當socket已經完整連接并準備好讀和寫數據時,將調用此方法。

     */

    - (void)socket:(MBGCDAsyncSocket *)socket didConnectToHost:(NSString*)host port:(uint16_t)port

    {

        if([ClientCoreSDK isENABLED_DEBUG])

            NSLog(@"【IMCORE-TCP-SOCKET】成收到的了TCP的connect反饋, isConnected? %d、已開啟ssl加密? %d", [socket isConnected], [ClientCoreSDK isSSL]);

     

        // 如果未開啟SSL加密傳輸,則正常進入連接完成后的代碼邏輯

        if(![ClientCoreSDK isSSL]) {

            [selfwhenDidConnect:socket];

        }

        // 如果已開啟SSL加密傳輸,則需要在回調中調用startTLS方法,以便實現跟服務端的SSL握手過程,

        // 如果ssl握手成功,則會通過 socketDidSecure: 回調通知開發者

        else{

            // 配置 SSL/TLS 設置信息

            NSMutableDictionary*settings = [NSMutableDictionarydictionaryWithCapacity:3];

            // 允許自簽名證書手動驗證

            [settings setObject:@YESforKey:GCDAsyncSocketManuallyEvaluateTrust];

            // 經測試,本項不設置并不影響SSL的啟用

    //      [settings setObject:@"此處填服務器IP地址" forKey:GCDAsyncSocketSSLPeerName];

            // 如果不是自簽名證書,而是權威證書頒發機構注冊申請的證書,這個settings字典可不傳(將使用GCDAsyncSocket的默認配置)

            [socket startTLS:settings];

        }

    }

     

    /**

     * 當SSL握手成功后(也就是上方調用startSSL:方法后),將調用此方法。

     */

    - (void)socketDidSecure:(MBGCDAsyncSocket *)socket

    {

        [selfwhenDidConnect:socket];

    }

     

    /**

     * Allows a socket delegate to hook into the TLS handshake and manually validate the peer it's connecting to.

     */

    - (void)socket:(MBGCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust completionHandler:(void(^)(BOOLshouldTrustPeer))completionHandler

    {

        NSLog(@"【IMCORE-TCP-SOCKET】didReceiveTrust...");

     

        // 以下沒有做更復雜的ssl證書驗證邏輯,如您需要實現更強大的雙向認證等邏輯,可以參考這里:

        // [url=https://github.com/FuangCao/cavan/blob/338ca8c09d6c78c5b38b95c6ffe994241afcc96e/xcode/TestSSL/TestSSL/ViewController.m]https://github.com/FuangCao/cava ... SL/ViewController.m[/url]

        if(completionHandler) {

            completionHandler(YES);

        }

    }

    說明:CocoaAsyncSocket中開啟SSL/TLS并不像Android和Java中那么簡單,它不只是幾行代碼的事,而是整個數據讀取邏輯的變化。

    PS:如果你想自已動手完整運行一下,可以閱讀《MobileIMSDK的Demo使用幫助:iOS版》。

    7.5Java桌面端如何開啟SSL/TLS

    Java桌面端開啟SSL/TLS的代碼跟Android端是一樣。我們同樣以 MobileIMSDKJava端開源代碼為例。

    Java桌面端開啟SSL/TLS加密的示例代碼片段:完整代碼詳見 IMClientManager.java

    /**

     * 創建SslContext對象,用于開啟SSL/TLS加密傳輸。

     *

     * @return 如果成功創建則返回SslContext對象,否則返回null

     */

    publicSslContext createSslContext() {

            SslContext sslContext = null;

            try{

                    sslContext = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();

                    Log.d(TAG, "【IMCORE-TCP】已開啟SSL/TLS加密(單向認證),且sslContext創建成功。");

            } catch(Exception e) {

                    Log.w(TAG, "【IMCORE-TCP】創建sslContext時出錯,原因是:"+ e.getMessage(), e);

            }

     

            returnsslContext;

    }

    PS:如果你想自已動手完整運行一下,可以閱讀《MobileIMSDK的Demo使用幫助:Java版》。

    7.6H5端如何開啟SSL/TLS

    我這里說的H5端,指的是能支持標準HTML5端WebSocket協議的PC瀏覽器端、手機移動端內嵌的Web引擎等場景。

    H5端能開啟SSL/TLS有兩個前提:

    • 1)第3方CA機構簽發的SSL/TLS證書(這條是關鍵,不然瀏覽器因安全原因會阻止WebSocket連接的建立);
    • 2)基于Netty的IM服務端已開啟SSL/TLS(見本章“7.2 基于Netty的IM服務端如何開啟SSL/TLS”)。

    滿足以上兩點后,H5端什么代碼都不需改動,只需將請求url由“ws”改成“wss”:

    8、參考資料

    [1] MobileIMSDK開源工程源碼

    [2] 史上最通俗Netty框架入門長文:基本介紹、環境搭建、動手實戰

    [3] 基于Netty,從零開發IM

    [4] 基于Netty的IM聊天加密技術學習:一文理清常見的加密概念、術語等

    [5] IM聊天系統安全手段之通信連接層加密技術

    [6] 通俗易懂:一篇掌握即時通訊的消息傳輸安全原理

    [7] 探討組合加密算法在IM中的應用

    [8] openssl安裝教程(windows7系統,超詳細)

    [9] WebSocket從入門到精通,半小時就夠!

    (本文已同步發布于:http://www.52im.net/thread-4142-1-1.html



    作者:Jack Jiang (點擊作者姓名進入Github)
    出處:http://www.52im.net/space-uid-1.html
    交流:歡迎加入即時通訊開發交流群 215891622
    討論:http://www.52im.net/
    Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
    本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: 一道本不卡免费视频| 2022久久国产精品免费热麻豆| 亚洲码国产精品高潮在线| 日韩免费人妻AV无码专区蜜桃| 亚洲人成7777| 在线观看亚洲天天一三视| 67pao强力打造国产免费| 女bbbbxxxx另类亚洲| 亚洲s色大片在线观看| 女人张腿给男人桶视频免费版| 久久久精品视频免费观看 | 亚洲色图黄色小说| 日韩免费观看视频| 国产拍拍拍无码视频免费| 久久久国产亚洲精品| 亚洲人成伊人成综合网久久久 | 亚洲电影日韩精品| 色影音免费色资源| 一级毛片免费视频网站| 亚洲jizzjizz在线播放久| 国产偷国产偷亚洲清高动态图| 成人免费视频网址| 久久99精品国产免费观看| 天天综合亚洲色在线精品| 亚洲伊人久久大香线蕉影院| 国产亚洲大尺度无码无码专线 | 亚洲JIZZJIZZ中国少妇中文| 日本免费一区二区在线观看| 国产成人无码精品久久久免费 | 国产亚洲美女精品久久| 亚洲日本在线播放| 国产亚洲一区二区精品| 国产免费爽爽视频免费可以看| 69av免费视频| 午夜老司机永久免费看片| 尤物视频在线免费观看| 中文字幕精品三区无码亚洲 | 亚洲香蕉久久一区二区三区四区| 国产成A人亚洲精V品无码| 亚洲国产精品一区二区九九| 免费黄色一级毛片|