關於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;
}
==============后面代碼有時間再上
