• 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;
            }
    

      

    ==============后面代码有时间再上

  • 相关阅读:
    [JSOI2007][BZOJ1030] 文本生成器|AC自动机|动态规划
    [NOI2014][BZOJ3670] 动物园|KMP
    [HAOI2010][BZOJ2427] 软件安装|tarjan|树型dp
    [JSOI2008][BZOJ1017] 魔兽地图DotR|树型dp
    [JLOI2014][BZOJ3631] 松鼠的新家|树上倍增LCA|差分
    [SDOI2010][BZOJ1975] 魔法猪学院|A*|K短路
    [BZOJ1251] 序列终结者|Splay
    hdu 2141 Can you find it?
    hdu 3152 Obstacle Course
    hdu 2680 Choose the best route
  • 原文地址:https://www.cnblogs.com/rbzz/p/11386094.html
Copyright © 2020-2023  润新知