FTP使用Socket SSL流程認證(一)


關於Ftp使用SSL流程認證

本文章使用的是C#,ftp服務器為FileZilla

注:如果不是使用的Socket可以使用FtpWebRequst類,說實話,該類比較簡單,但現在說的是SOCKET,網上關於這方面的實在太少了

流程(不會畫圖,就筆述)

大致流程:

一.ssl的認證

1.連接到指定的ftp服務器(當前還未登陸)

2.發送"AUTH SSL"或"AUTH TLS"命令,返回234則成功

3.使用剛才連接的socket創建SSLSTream對象

  創建對象示例如下

 Socket mClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint mEPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 21);
            mClientSocket.Connect(mEPoint);
            //發送ssl命令
            SendCommand("AUTH SSL");
            NetworkStream network = new NetworkStream(mClientSocket);
            SslStream sslStream = new SslStream(network, true, (o,i,s,j)=>true, null);
        //ssl驗證 sslStream.AuthenticateAsClient("certName", null, System.Security.Authentication.SslProtocols.Ssl3 | System.Security.Authentication.SslProtocols.Tls, true);

4.成功驗證后發送USER,PASS等命令(此時發送命令以及接收返回值都應當使用第三步創建的"sslStream"對象,所以需要有一個全局變量來保存該對象)

5.發送"PBSZ 0"命令,發送"PROT P"命令,登陸完成

6.以讀取目錄中文件為例

  6.1 在獲取到端口並創建了DataSocket后,發送"LIST"命令之后,應當以DataSocket創建一個SslStream對象出來,並且進行ssl驗證

  6.2 使用第3步的的SslStream對象獲取一下返回值(否則后面獲取文件列表會有問題)

  6.3 在6.2完成后使用6.1的SslStream對象獲取返回值,即是當前目錄的所有文件/目錄列表

 

注意:

1.socket ssl認證需要兩個sslStream對象,一個是連接的sslStream對象,該對象在創建並驗證成功后主要用來向ftp服務器發送命令,在未創建數據的sslStream對象時獲取服務器返回信息也使用該對象

2.另一個為數據對象,當創建了一個傳輸端口的Socket並創建其sslStream對象並驗證后,后續的向ftp發送命令,以及獲取返回值均使用的該對象

3.關於如何使用傳輸socket的sslstream來獲取返回值

這一步也是困擾我很久的,因為sslStream沒有方法可以知道當前流中還剩下多少數據,使用ReadByte方法會阻塞線程

所以我把傳輸的DataSocket給保存到全局變量中,使用DataSocket可以知道剩下的數據量

示例方法如下:

/// <summary>
        /// 獲取服務器返回信息
        /// </summary>
        /// <param name="byteSize">緩沖區大小</param>
        /// <returns></returns>
        public List<byte> Receive(int byteSize)
        {
            byte[] buffer = new byte[byteSize];
            string result = string.Empty;
            List<byte> list = new List<byte>();
            do
            {
                //使用傳輸的sslStream來獲取返回信息
                int byts = DataSSLStream.Read(buffer, 0, buffer.Length);
                list.AddRange(buffer.Take(byts));

                //查看當前的傳輸socket中是否還有數據
                if (DataSocket.Available == 0)
                {
                    break;
                }

            } while (true);
            return list;
        }

  

==============后面代碼有時間再上

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM