日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

证书的应用之一 —— TCPSSL通信实例及协议分析(上)

發(fā)布時間:2023/12/18 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 证书的应用之一 —— TCPSSL通信实例及协议分析(上) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

SSL(Security Socket Layer)是TLS(Transport Layer Security)的前身,是一種加解密協(xié)議,它提供了再網(wǎng)絡(luò)上的安全傳輸,它介于網(wǎng)絡(luò)通信協(xié)議的傳輸層與應(yīng)用層之間。

為實現(xiàn)TCP層之上的ssl通信,需要用到數(shù)字證書。本文通過具體例子來說明如何使用數(shù)字證書來實現(xiàn)網(wǎng)絡(luò)上的安全傳輸。需要用到.net提供的SslStream, TcpListener, TcpClient, X509Certificate2,X509Store,X509Certification2Collection等類。終于開始涉及到代碼了。

一.服務(wù)器端

1.指定證書

常用的有兩種方式:從文件獲取和從certificate store中獲取

a.從文件

從文件讀取證書 1 OpenFileDialog dialog = new OpenFileDialog();
2 dialog.Filter = "Cert files(*.pfx;*.p7b;*.cer)|*.pfx;*.p7b;*.cer|All files(*.*)|*.*";
3 DialogResult dr = dialog.ShowDialog();
4 if (dr == DialogResult.OK)
5 {
6 Console.WriteLine("Input the password for the cert:");
7 StringBuilder stringBuilder = new StringBuilder();
8 while (true)
9 {
10 ConsoleKeyInfo passInfo = Console.ReadKey(true);
11 if (passInfo.Key == ConsoleKey.Enter)
12 {
13 break;
14 }
15 stringBuilder.Append(passInfo.KeyChar);
16 }
17 return new X509Certificate2(dialog.FileName, stringBuilder.ToString(), X509KeyStorageFlags.Exportable);
18 }
19 else
20 {
21 return null;
22 }

注意X509Certificate2構(gòu)造函數(shù)第三個參數(shù),如果想把調(diào)用Export方法將cert對象到處,此處必須使用Exportable標記,否則在導(dǎo)出時會拋出異常。

pfx格式的證書包含有private key,因此需要密碼的保護,構(gòu)造函數(shù)的第二個參數(shù)就是密碼。

選取的證書必須包含有private key,否則在SSL的server端使用時會拋出AuthenticationException。

怎么得到pfx文件:使用MMC->File->Add/Remove Sanp-in->Add->Certificates->Add->My user account/Computer account->Finish 查看存儲在本機當前用戶和所有用戶的證書,選擇用導(dǎo)出的證書,

右鍵->All Tasks...->Export...注意要勾選[Yes, export the private key],如果該Radio button被禁用,說明該證書的private key不能被導(dǎo)出,可能是在導(dǎo)入該證書時沒有選擇標記private key為可導(dǎo)出,如下圖所示:

b.從certificate store

?

從store讀取證書 1 X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
2 store.Open(OpenFlags.ReadOnly);
3 X509Certificate2Collection collection = X509Certificate2UI.SelectFromCollection(store.Certificates,
4 "Select Certificate",
5 "Please select a certificate from the following list",
6 X509SelectionFlag.SingleSelection);

注意:

Server端指定的cert必須含有privatekey,且Enhanced key usage必須含有Server Authentication (1.3.6.1.5.5.7.3.1)

沒有private key

NotSupportedException: The server modeSSL must use a certificate with the associated private key.

證書purpose不對:

server端:AuthenticationException: A call to SSPIfailed, see inner exception.

client端:IOException: Unable to read data from the transport connection: Anexisting connection was forcibly closed by the remote host..

2.開始TCP監(jiān)聽

?

TCP監(jiān)聽 1 TcpListener listener = new TcpListener(IPAddress.Any, 8080);
2 listener.Start();
3 while (true)
4 {
5 Console.WriteLine("Waiting for a client to connect...");
6 TcpClient client = listener.AcceptTcpClient();
7 ......
8 }

?

3.指定服務(wù)器證書

?

指定服務(wù)器證書 1 // A client has connected. Create the
2 // SslStream using the client's network stream.
3 ? SslStream sslStream = new SslStream(client.GetStream(), false);
4 // Authenticate the server but don't require the client to authenticate.
5 ? try
6 {
7 sslStream.AuthenticateAsServer(cert, false, SslProtocols.Default, false);
8
9 // Set timeouts for the read and write to 5 seconds.
10 ? sslStream.ReadTimeout = 5000;
11 sslStream.WriteTimeout = 5000;
12 ......
13 }

?

4.發(fā)送數(shù)據(jù)

?

1 byte[] message = Encoding.UTF8.GetBytes("Hello from the server.<EOF>");
2 sslStream.Write(message);
3 sslStream.Flush();

?

5.接收數(shù)據(jù)

?

接收數(shù)據(jù) 1 byte[] buffer = new byte[2048];
2 StringBuilder messageData = new StringBuilder();
3 int bytes = -1;
4 do
5 {
6 // Read the client's message.
7 ? bytes = sslStream.Read(buffer, 0, buffer.Length);
8 messageData.Append(Encoding.UTF8.GetString(buffer, 0, bytes));
9 // Check for EOF or an empty message.
10 ? if (messageData.ToString().IndexOf("<EOF>") != -1)
11 {
12 break;
13 }
14 } while (bytes != 0);
15
16 return messageData.ToString();

?

注意:Write后需要調(diào)用Flush將數(shù)據(jù)立刻發(fā)送,Read需要多次調(diào)用,確定讀不到數(shù)據(jù)位置,因為TCP連接時Stream方式的,在網(wǎng)絡(luò)中傳輸可能會分包到達,一次無法全部讀取,還需要消息邊界。

6.結(jié)束

?

1 sslStream.Close();
2 client.Close();

?

二.客戶端

1.與服務(wù)器端建立TCP連接

?

1 TcpClient client = new TcpClient(machineName, 8080);

2.與服務(wù)端建立SSL握手

?

客戶端與服務(wù)端建立SSL握手 1 SslStream sslStream = new SslStream(
2 client.GetStream(),
3 false,
4 new RemoteCertificateValidationCallback(ValidateServerCertificate),
5 null
6 );
7 try
8 {
9 // The server name must match the name on the server certificate.
10 ? X509Certificate2 cert = GetCert();
11 X509Certificate2Collection collection = new X509Certificate2Collection();
12 if(cert != null)
13 {
14 collection.Add(cert);
15 }
16 sslStream.AuthenticateAsClient(serverName, collection, SslProtocols.Default, false);
17 }
18 catch (AuthenticationException e)
19 {
20 Console.WriteLine("Exception: {0}", e.Message);
21 if (e.InnerException != null)
22 {
23 Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
24 }
25 Console.WriteLine("Authentication failed - closing the connection.");
26 client.Close();
27 return;
28 }

?

如果服務(wù)端在調(diào)用AuthenticateAsServer方法時指定不需要客戶端的證書,則客戶端在調(diào)用AuthenticateAsClient時可以不指定證書,

如果serverAuthenticateAsServer是指定client需要cert,而client在調(diào)用AuthenticateAsClient時沒有指定cert或者cert沒有private key時:

server端:AuthenticationExceptionThe remote certificate is invalid according to the validationprocedure.

client端:IOException: Unable to read data from the transportconnection: An established connection was aborted by the software in your hostmachine.

?

ClientAuthenticateAsClient方法指定的名字需要與server端使用cert的名字一致,否則在RemoteCertificateValidationCallback事件中SslPolicyErrors會是RemoteCertificateNameMismatch

3.發(fā)送接收數(shù)據(jù),關(guān)閉連接,與服務(wù)器端方法相同


使用Wireshark Network Analyzer工具進行抓包分析,發(fā)現(xiàn)在建立TCP連接后,首先進行SSL握手,之后傳輸?shù)臄?shù)據(jù)都是被加密的,如下圖所示:


對SSL的握手和加密傳輸?shù)脑敿氝^程,將在下節(jié)分析。

下載Demo

轉(zhuǎn)載于:https://www.cnblogs.com/piyeyong/archive/2010/06/20/1761458.html

總結(jié)

以上是生活随笔為你收集整理的证书的应用之一 —— TCPSSL通信实例及协议分析(上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。