FTP使用Socket SSL流程認(rèn)證(一)
關(guān)于Ftp使用SSL流程認(rèn)證
本文章使用的是C#,ftp服務(wù)器為FileZilla
注:如果不是使用的Socket可以使用FtpWebRequst類,說實(shí)話,該類比較簡單,但現(xiàn)在說的是SOCKET,網(wǎng)上關(guān)于這方面的實(shí)在太少了
流程(不會畫圖,就筆述)
大致流程:
一.ssl的認(rèn)證
1.連接到指定的ftp服務(wù)器(當(dāng)前還未登陸)
2.發(fā)送"AUTH SSL"或"AUTH TLS"命令,返回234則成功
3.使用剛才連接的socket創(chuàng)建SSLSTream對象
創(chuàng)建對象示例如下
Socket mClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint mEPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 21);
mClientSocket.Connect(mEPoint);
//發(fā)送ssl命令
SendCommand("AUTH SSL");
NetworkStream network = new NetworkStream(mClientSocket);
SslStream sslStream = new SslStream(network, true, (o,i,s,j)=>true, null);
//ssl驗(yàn)證
sslStream.AuthenticateAsClient("certName", null, System.Security.Authentication.SslProtocols.Ssl3 | System.Security.Authentication.SslProtocols.Tls, true);
4.成功驗(yàn)證后發(fā)送USER,PASS等命令(此時(shí)發(fā)送命令以及接收返回值都應(yīng)當(dāng)使用第三步創(chuàng)建的"sslStream"對象,所以需要有一個(gè)全局變量來保存該對象)
5.發(fā)送"PBSZ 0"命令,發(fā)送"PROT P"命令,登陸完成
6.以讀取目錄中文件為例
6.1 在獲取到端口并創(chuàng)建了DataSocket后,發(fā)送"LIST"命令之后,應(yīng)當(dāng)以DataSocket創(chuàng)建一個(gè)SslStream對象出來,并且進(jìn)行ssl驗(yàn)證
6.2 使用第3步的的SslStream對象獲取一下返回值(否則后面獲取文件列表會有問題)
6.3 在6.2完成后使用6.1的SslStream對象獲取返回值,即是當(dāng)前目錄的所有文件/目錄列表
注意:
1.socket ssl認(rèn)證需要兩個(gè)sslStream對象,一個(gè)是連接的sslStream對象,該對象在創(chuàng)建并驗(yàn)證成功后主要用來向ftp服務(wù)器發(fā)送命令,在未創(chuàng)建數(shù)據(jù)的sslStream對象時(shí)獲取服務(wù)器返回信息也使用該對象
2.另一個(gè)為數(shù)據(jù)對象,當(dāng)創(chuàng)建了一個(gè)傳輸端口的Socket并創(chuàng)建其sslStream對象并驗(yàn)證后,后續(xù)的向ftp發(fā)送命令,以及獲取返回值均使用的該對象
3.關(guān)于如何使用傳輸socket的sslstream來獲取返回值
這一步也是困擾我很久的,因?yàn)閟slStream沒有方法可以知道當(dāng)前流中還剩下多少數(shù)據(jù),使用ReadByte方法會阻塞線程
所以我把傳輸?shù)腄ataSocket給保存到全局變量中,使用DataSocket可以知道剩下的數(shù)據(jù)量
示例方法如下:
/// <summary>
/// 獲取服務(wù)器返回信息
/// </summary>
/// <param name="byteSize">緩沖區(qū)大小</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
{
//使用傳輸?shù)膕slStream來獲取返回信息
int byts = DataSSLStream.Read(buffer, 0, buffer.Length);
list.AddRange(buffer.Take(byts));
//查看當(dāng)前的傳輸socket中是否還有數(shù)據(jù)
if (DataSocket.Available == 0)
{
break;
}
} while (true);
return list;
}
==============后面代碼有時(shí)間再上

浙公網(wǎng)安備 33010602011771號