用TLS实现安全TCP传输及配置和访问https的web服务(转)
tls相關
大致原理
為了讓兩個之間實現安全傳輸,(我們把服務端統一叫做TcpServer,客戶端統一叫做TcpClient),TcpServer在listen完了accept之后要用一個證書來聲明自己是誰,而TcpClient在connect之后要問TcpServer是否具有自己想要的一個證書(確認服務端身份),如果是自己指定的那個證書,就說明是自己要連接的那個TcpServer,這時候連接就會建立成功,以后發給TcpServer的數據,都會用TcpServer聲明的證書里面的公鑰來加密后再發送給TcpServer,TcpServer會用自己機器里的私鑰對數據解密。
以上保證了TcpClient不會連接到非法的TcpServer,第三方截取TcpClient發送的數據也解不開。
然后TcpServer也可以(可選)要求TcpClient必須提供證書,用以證明是傳入的TcpClient自己信任的TcpClient。TcpClient會把證書(從某個CA申請的)進行簽名后發送給TcpServer,TcpServer會確認TcpClient提供的證書發行者是否是自己信任的發行者(就是是否裝有這個發行者的根證書),如果信任就會建立連接成功。
以上保證了TcpServer和TcpClient之間實現了雙向的身份驗證,建立了信任連接。這時候TcpServer和TcpClient會各自用一定的算法生成一個密鑰做為會話密鑰,并通知給對方,之后相互傳輸數據就用這個會話密鑰進行對稱加密后傳給對方,這樣做是因為對稱加密比非對稱加密性能要好一個數量級。(密鑰交換一般是服務端用一段隨機數傳給客戶端,客戶端用一段隨機數傳給服務端,這個傳輸是安全傳輸,然后雙方用兩個隨機數合并起來的一個數做為會話密鑰)
其中的用sha1做為消息完整性算法,3des做為消息機密性算法,rsa做為密鑰交換算法(在安全策略里打開fips選項 )。
證書相關操作
申請服務端證書
先找一臺機器裝上證書頒發服務(在添加/刪除程序-添加刪除windows組件里),然后再另一臺機器通過瀏覽器申請證書,該網址類似如下(其中ms-onlytiancai為證書服務器機器名):
http://ms-onlytiancai/certsrv/
選擇高級申請證書,如下圖,識別信息要填全,否則客戶端驗證的時候會出現證書鏈(我測的時候確實如此,但證書鏈的概念是根CA和多級的中級CA之間信任關系的一個鏈,具體看相關鏈接)失敗。d
證書類型要選擇“服務器身份驗證證書(有些CA可能沒有單獨的這樣的模板,那就選擇“計算機副本”證書,該證書可以用來驗證服務器身份和客戶端身份)”,其它選項不要動,最后點申請,然后再在CA服務器的【管理工具】-【證書頒發機構】的“掛起的證書”里把剛申請的證書頒發一下,最后還在證書申請網頁上點“查看掛起的證書申請的狀態”,通過向導,安裝證書,提示你是否信任該CA時,點是,這時候會自動把該證書安裝到“個人”區域,并把該CA證書安裝到“受信任的根證書頒發機構”。這一步是必須的,這樣做服務端就會信任該CA發行的所有證書(如果這一步沒有安裝根證書,后面可以從控制臺里把CA證書單獨導入到本地計算機的受信任頒發機構里,CA證書不是申請的,是直接在證書申請頁面的下方的鏈接下載的),后面申請客戶端證書的時候也從這個CA來申請,服務端才會信任這個客戶端。
申請客戶端證書
過程和申請服務端證書一樣,只是證書類型選擇“客戶端身份驗證證書”。
導出證書
在證書管理控制臺里把服務端證書和客戶端證書全部導出到本地,導出選項全部為默認。
服務器為:C:"certs"huhao.pxe(帶私鑰)
客戶端為:C:"certs"client.cer
如果服務端為windows服務,需要把服務端證書導入到本地計算機里,默認服務器證書只安裝到了當前用戶的個人區域,需要從當前用戶的個人區域導出來,再導入到本地計算機的個人區域,導出的時候記著選上導出私鑰,否則導入到本地計算機里的證書就不會關聯私鑰了。
應用相關
服務端代碼
??
?
類庫using?System;
using?System.Net.Sockets;
using?System.Net;
using?System.Net.Security;
using?System.Security.Cryptography.X509Certificates;
using?System.Text;
using?System.Security.Authentication;
using?System.Threading;
class?TCPServer_SSL
{
????private?TcpListener?_listener?=?null;
????private?IPAddress?_address?=?IPAddress.Parse("127.0.0.1");
????private?int?_port?=?55555;
????CTORs#region?CTORs
????public?TCPServer_SSL()
????{
????}
????public?TCPServer_SSL(string?address,?string?port)
????{
????????_port?=?Convert.ToInt32(port);
????????_address?=?IPAddress.Parse(address);
????}
????#endregion?//?CTORs
????Properties#region?Properties
????public?IPAddress?Address
????{
????????get?{?return?_address;?}
????????set?{?_address?=?value;?}
????}
????public?int?Port
????{
????????get?{?return?_port;?}
????????set?{?_port?=?value;?}
????}
????#endregion
????public?void?Listen()
????{
????????try
????????{
????????????_listener?=?new?TcpListener(_address,?_port);
????????????//?Fire?up?the?server.
????????????_listener.Start();
????????????//?Enter?the?listening?loop.
????????????while?(true)
????????????{
????????????????Console.Write("Looking?for?someone?to?talk?to…?");
????????????????//?Wait?for?connection.
????????????????TcpClient?newClient?=?_listener.AcceptTcpClient();
????????????????Console.WriteLine("Connected?to?new?client");
????????????????//?Spin?a?thread?to?take?care?of?the?client.
????????????????ThreadPool.QueueUserWorkItem(new?WaitCallback(ProcessClient),
?????????????????????????????????????????newClient);
????????????}
????????}
????????catch?(SocketException?e)
????????{
????????????Console.WriteLine("SocketException:?{0}",?e);
????????}
????????finally
????????{
????????????//?Shut?it?down.
????????????_listener.Stop();
????????}
????????Console.WriteLine("/nHit?any?key?(where?is?ANYKEY?)?to?continue…");
????????Console.Read();
????}
????private?void?ProcessClient(object?client)
????{
????????using?(TcpClient?newClient?=?(TcpClient)client)
????????{
????????????//?Buffer?for?reading?data.
????????????byte[]?bytes?=?new?byte[1024];
????????????string?clientData?=?null;
????????????//第三個參數是驗證客戶端證書的回調,最后一個參數是用來指定多個證明自己的證書的回調,這里為空
????????????//前兩個參數分別是一個流和是否在關閉sslstrem關閉內部流的選項
????????????using?(SslStream?sslStream?=?new?SslStream(newClient.GetStream(),?false,?ValidateClientCertificate,null))
????????????{
????????????????try
????????????????{
????????????????????//該方法的第一個參數是用于服務端身份驗證的證書,第二個參數指定是否需要驗證客戶端的身份
????????????????????//第三個參數是指定安全傳輸的協議,最后一個參數指定是否檢查吊銷證書
????????????????????sslStream.AuthenticateAsServer(GetServerCert("117f32ff000000000007"),?true,?SslProtocols.Tls,?false);
????????????????}
????????????????catch?(Exception?ex)
????????????????{
????????????????????Console.WriteLine(ex);
????????????????}
????????????????//?Loop?to?receive?all?the?data?sent?by?the?client.
????????????????int?bytesRead?=?0;
????????????????while?((bytesRead?=?sslStream.Read(bytes,?0,?bytes.Length))?!=?0)
????????????????{
????????????????????//?Translate?data?bytes?to?an?ASCII?string.
????????????????????clientData?=?Encoding.ASCII.GetString(bytes,?0,?bytesRead);
????????????????????Console.WriteLine("Client?says:?{0}",?clientData);
????????????????????//?Thank?them?for?their?input.
????????????????????bytes?=?Encoding.ASCII.GetBytes("Thanks?call?again!");
????????????????????//?Send?back?a?response.
????????????????????sslStream.Write(bytes,?0,?bytes.Length);
????????????????}
????????????}
????????}
????}
????public?static?bool?ValidateClientCertificate(object?sender,?X509Certificate?certificate,?X509Chain?chain,?SslPolicyErrors?sslPolicyErrors)
????{
????????Console.WriteLine("ValidateClientCertificate-certificate.Subject:/r/n{0}",?certificate.Subject);
????????if?(sslPolicyErrors?!=?SslPolicyErrors.None?&&?sslPolicyErrors?!=?SslPolicyErrors.RemoteCertificateChainErrors)
????????????return?false;
????????if?(sslPolicyErrors?!=?SslPolicyErrors.RemoteCertificateChainErrors)
????????{
????????????//不判斷吊銷證書
????????????foreach?(X509ChainStatus?s?in?chain.ChainStatus)
????????????{
????????????????Console.WriteLine("ValidateClientCertificate-chain.ChainStatus:/r/n{0}-{1}",?s.Status,?s.StatusInformation);
????????????????if?(s.Status?!=?X509ChainStatusFlags.OfflineRevocation?&&?s.Status?!=?X509ChainStatusFlags.RevocationStatusUnknown)
????????????????{
????????????????????return?false;
????????????????}
????????????}
????????}
????????return?true;
????}
????//該方法從本地計算機的個人證書區域按證書序列號查找指定的證書用于服務器身份驗證
????//以及打印出證書的詳細信息
????private?static?X509Certificate?GetServerCert(string?serialNumber)
????{
????????X509Store?store?=?new?X509Store(StoreName.My,?StoreLocation.CurrentUser);
????????try
????????{
????????????store.Open(OpenFlags.ReadOnly);
????????????X509Certificate2Collection?certificate?=
????????????????????store.Certificates.Find(X509FindType.FindBySerialNumber,
????????????????????????????????????????????serialNumber,?true);
????????????X509Certificate2?x509?=?certificate[0];
????????????byte[]?rawdata?=?x509.RawData;
????????????Console.WriteLine("509?count?:{0}",?store.Certificates.Count);
????????????Console.WriteLine("Content?Type:?{0}{1}",?X509Certificate2.GetCertContentType(rawdata),?Environment.NewLine);
????????????Console.WriteLine("Friendly?Name:?{0}{1}",?x509.FriendlyName,?Environment.NewLine);
????????????Console.WriteLine("Certificate?Verified?:?{0}{1}",?x509.Verify(),?Environment.NewLine);
????????????Console.WriteLine("Simple?Name:?{0}{1}",?x509.GetNameInfo(X509NameType.SimpleName,?true),?Environment.NewLine);
????????????Console.WriteLine("Signature?Algorithm:?{0}{1}",?x509.SignatureAlgorithm.FriendlyName,?Environment.NewLine);
????????????Console.WriteLine("Private?Key:?{0}{1}",?x509.PrivateKey.ToXmlString(false),?Environment.NewLine);
????????????Console.WriteLine("Public?Key:?{0}{1}",?x509.PublicKey.Key.ToXmlString(false),?Environment.NewLine);
????????????Console.WriteLine("Certificate?Archived?:?{0}{1}",?x509.Archived,?Environment.NewLine);
????????????Console.WriteLine("Length?of?Raw?Data:?{0}{1}",?x509.RawData.Length,?Environment.NewLine);
????????????Console.WriteLine("x509.SerialNumber:?{0}{1}",?x509.SerialNumber,?Environment.NewLine);
????????????if?(certificate.Count?>?0)
????????????????return?(certificate[0]);
????????????else
????????????????return?(null);
????????}
????????catch?(Exception?ex)
????????{
????????????Console.WriteLine(ex);
????????????return?null;
????????}
????????finally
????????{
????????????store.Close();
????????}
????}
}
?
控制臺代碼?static?void?Main(string[]?args)
????????{
????????????try
????????????{
????????????????TCPServer_SSL?server?=?new?TCPServer_SSL("127.0.0.1",?"8000");
????????????????server.Listen();
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????Console.WriteLine(ex);
????????????}
????????????Console.Read();
????????}
?
客戶端
?
類庫using?System;
using?System.Net.Sockets;
using?System.Net;
using?System.Net.Security;
using?System.Security.Cryptography.X509Certificates;
using?System.Text;
class?TCPClient_SSL
{
????private?TcpClient?_client?=?null;
????private?IPAddress?_address?=?IPAddress.Parse("127.0.0.1");
????private?int?_port?=?5;
????private?IPEndPoint?_endPoint?=?null;
????public?TCPClient_SSL(string?address,?string?port)
????{
????????_address?=?IPAddress.Parse(address);
????????_port?=?Convert.ToInt32(port);
????????_endPoint?=?new?IPEndPoint(_address,?_port);
????}
????public?void?ConnectToServer(string?msg)
????{
????????try
????????{
????????????using?(_client?=?new?TcpClient())
????????????{
????????????????_client.Connect(_endPoint);
????????????????//SslStream第一個參數是一個流,可以是由用Socket類new的一個NetworkStream
????????????????//第二個參數為false的時候,關閉sslStream就會關閉對應的NetworkStream
????????????????//第三個參數是一個回調,用來控制服務端的驗證
????????????????using?(SslStream?sslStream?=?new?SslStream(_client.GetStream(),
????????????????????????????????false,?new?RemoteCertificateValidationCallback(
????????????????????????????????????ValidateServerCertificate)))
????????????????{
????????????????????X509CertificateCollection?cert?=?new?X509CertificateCollection();
????????????????????//下面是從一個導出證書文件里加載證書
????????????????????X509Certificate?cer?=?X509Certificate2.CreateFromCertFile("c://certs//huhao.cer");
????????????????????cert.Add(cer);
????????????????????//AuthenticateAsClient方法第一個參數要寫服務端證書的名字,和服務器的機器名和dns名應一致
????????????????????//第二個參數是一個證書集合,如果是多個證書,可以在一個回調函數里選擇指定證書用以驗證客戶端
????????????????????//第三個參數指定安全傳輸的協議,可以是ssl,tls的不同版本
????????????????????//最后一個參數表示是否檢查吊銷證書列表,吊銷證書是定時推給服務器的,驗證起來比較耗性能
????????????????????sslStream.AuthenticateAsClient("ms-7fa82788ed1e",?cert,?System.Security.Authentication.SslProtocols.Tls,?false);
????????????????????sslStream.ReadTimeout?=?5000;
????????????????????sslStream.WriteTimeout?=?5000;
????????????????????//?Get?the?bytes?to?send?for?the?message.
????????????????????byte[]?bytes?=?Encoding.ASCII.GetBytes(msg);
????????????????????//?Send?message.
????????????????????Console.WriteLine("Sending?message?to?server:?"?+?msg);
????????????????????//這里可以使用BeginWrite
????????????????????sslStream.Write(bytes,?0,?bytes.Length);
????????????????????//?Get?the?response.
????????????????????//?Buffer?to?store?the?response?bytes.
????????????????????bytes?=?new?byte[1024];
????????????????????//?Display?the?response.
????????????????????//這里可以使用BeginRead
????????????????????int?bytesRead?=?sslStream.Read(bytes,?0,?bytes.Length);
????????????????????string?serverResponse?=?Encoding.ASCII.GetString(bytes,?0,
??????????????????????????bytesRead);
????????????????????Console.WriteLine("Server?said:?"?+?serverResponse);
????????????????}
????????????}
????????}
????????catch?(SocketException?e)
????????{
????????????Console.WriteLine("There?was?an?error?talking?to?the?server:?{0}",
????????????e.ToString());
????????}
????}
????private?bool?ValidateServerCertificate(object?sender,
???????????????????????????????????????????????X509Certificate?certificate,
???????????????????????????????????????????????X509Chain?chain,
???????????????????????????????????????????????SslPolicyErrors?sslPolicyErrors)
????{
????????if?(sslPolicyErrors?==?SslPolicyErrors.None)
????????{
????????????return?true;
????????}
????????else
????????{
????????????if?(sslPolicyErrors?==?SslPolicyErrors.RemoteCertificateChainErrors)
????????????{
????????????????Console.WriteLine("The?X509Chain.ChainStatus?returned?an?array?"?+
???????????????????"of?X509ChainStatus?objects?containing?error?information.");
????????????}
????????????else?if?(sslPolicyErrors?==
?????????????????????SslPolicyErrors.RemoteCertificateNameMismatch)
????????????{
????????????????Console.WriteLine("There?was?a?mismatch?of?the?name?"?+
??????????????????"on?a?certificate.");
????????????}
????????????else?if?(sslPolicyErrors?==
?????????????????????SslPolicyErrors.RemoteCertificateNotAvailable)
????????????{
????????????????Console.WriteLine("No?certificate?was?available.");
????????????}
????????????else
????????????{
????????????????Console.WriteLine("SSL?Certificate?Validation?Error!");
????????????}
????????}
????????Console.WriteLine(Environment.NewLine?+
??????????????????????????"SSL?Certificate?Validation?Error!");
????????Console.WriteLine(sslPolicyErrors.ToString());
????????return?false;
????}
}
控制臺
static?void?Main(string[]?args)????????{
????????????try
????????????{
????????????????TCPClient_SSL?client?=?new?TCPClient_SSL("127.0.0.1",?"8000");
????????????????client.ConnectToServer("11111");
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????Console.WriteLine(ex);
????????????}
????????????Console.Read();
????????}
?
注意事項
1.???????? 如果TcpServer是一個windows服務,用于服務端的證書不能用X509Certificate2.CreateFromCertFile方法加載導出的證書文件來獲取,而應該用相關API來讀取本地計算機證書存儲器的my區域的證書,查找可以按證書序列號來查,具體代碼大約如下。
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
?? ?????????store.Open(OpenFlags.ReadOnly);
??????????? X509Certificate2Collection cert = store.Certificates.Find(X509FindType.FindBySerialNumber,
??????????? “611cea09000000000002”, false);
??????????? _certificate = cert[0];
2.???????? 如果是服務端是windows服務,由于windows服務運行賬戶是本地系統賬戶,并不是某個具體用戶,所以這時候用于服務端驗證的證書應該導入到本地計算機的my(個人)區域,然后本地計算的“受信任的根證書頒發機構“要導入客戶端證書的CA證書(在客戶端證書申請頁有下載鏈接)。
3.???????? 出現“啟用服務端SSL必須使用關聯私鑰的證書“(The server mode SSL must use a certificate with the associated private key.)是因為服務端用的證書是從文件里取的,而不是通過證書存儲API取出來的,一般是這個問題。
4.???????? 出現“沒有識別提供給安全軟件包的憑證“(System.Net.SSPIWrapper.AcquireCredentialsHandle方法)的錯誤,可能是因為你的機器是虛擬機,或者你試著重啟一下試試能否解決,該問題出現后,代碼幾乎沒變,后來就好了。
5.???????? 通過證書申請頁面申請的證書一般會安裝在當前用戶的個人存儲區,如果要把這個證書安裝到計算機里,可以在證書管理控制臺里把用戶個人區域里的證書連私鑰導出成pfx文件(不是.cer文件),然后在在證書管理控制臺(開始-運行-輸入mmc.exe,在添加刪除管理單元里把“證書“單元添加進來,可以選擇當前用戶和計算機)里導入到計算機的個人區域里。
6.???????? 可以使用SslStream的異步讀寫方法來提高性能
7.???????? 從證書存儲區獲取證書的時候用證書序列號比較容易精確的獲取證書,比用subject等要準確
8.???????? SslStream.AuthenticateAsClientd的targetHost參數為客戶端驗證的服務端證書名稱,就是服務器認證證書的“頒發給“字段。這里一定要寫對,既不是CA的服務器地址,也不是類似http://ms-onlytiancai/certsrv/的字符串,也不是TcpServer的地址(實際上是TcpServer的netbios名稱或dns名稱,和申請服務器證書時的姓名字段是一個,必須相同)。如果填寫其它字符串,在客戶端驗證的時候會出RemoteCertificateNameMismatch錯誤。
https webServices
服務端配置SSL(https)
1.???????? 在IIS的默認網站的屬性-目錄安全性-安全通信-服務器證書對話框里,選擇新建一個證書,按照向導,一路向下,到“站點公用名稱列”,在“公用名稱”里輸入服務器的dns名稱或者netbios名稱,這里一定要填寫對,最后會在硬盤上生成一個cerreq.txt文件的服務器證書申請單。
2.???????? 把上一步生成的申請單傳給CA,在CA服務器的“證書頒發機構”管理器上右鍵點“新建證書申請”,在彈出的對話框里選擇cerreq.txt,確定后“掛起的證書”節點會多一個證書申請,右鍵點“頒發”。頒發后在到“已頒發的證書”節點里找到剛剛頒發的證書,右鍵點“導出”,對話框里在“包含二進制的列”下拉框里選擇“二進制證書”,然后選擇“保存證書到一個文件”,最后會在硬盤上生成一個.cer文件(應該是帶私鑰的)。
3.???????? 在服務器上拷貝一下上一步生成的.cer文件,再在IIS屬性的目錄安全性-安全通信-服務器證書,彈出一個“歡迎使用web服務器證書向導”對話框,下一步后選擇“處理已掛起的證書申請”,下一步中選擇拷貝過來的.cer文件,再下一步選443端口。
4.???????? 然后在你的web服務的虛擬目錄-目錄安全性-安全通信-點編輯按鈕,把“要求安全通道(ssl)”的復選框打上,如果需要驗證客戶端證書的話,在“客戶端證書”單選框列表里選擇“要求客戶端證書”。如果選擇了“要求客戶端證書”,可以在下面的“啟用客戶端證書映射”的“編輯”對話框里把證書映射到服務器的指定賬戶。
5.???????? 如果啟用了“要求客戶端證書”,服務器要信任客戶端證書的CA,具體操作如下。開始-運行,輸入mmc.exe。在控制臺里點文件-添加/刪除管理單元,選擇“證書”單元,然后點添加的時候選擇“計算機賬戶-本地計算機”(一定要選對,如果選擇“我的用戶賬戶的話,只是當前賬戶信任某個CA,當前計算機不會信任指定CA的”)。然后在證書控制臺里的“受信任的頒發機構”節點上右鍵點導入,把在證書申請頁面上下載的CA證書導入進來。這樣這臺服務器就新人所有這個CA頒發的客戶端證書了。
客戶端訪問
1、?先為客戶端申請一個客戶端證書,CA就用服務器計算機信任的CA。
2、?編碼,如下,假設cxz計算機上有一個service的服務,有個helloworld方法
?
源碼下載地址
http://files.cnblogs.com/onlytiancai/ssltest.rar
相關鏈接:
Securing Stream Data
http://codeidol.com/csharp/csharpckbk2/Security/Securing-Stream-Data/
構建基于windows證書服務的公鑰基礎結構
http://bbs.51cto.com/thread-426225-1-1.html
Windows 2000 公鑰基礎結構詳解
http://www.cnblogs.com/coldwine/archive/2005/08/31/227071.html
聲明:本文代碼修改自相關鏈接的第一篇文章
原文出自:
http://www.cnblogs.com/onlytiancai/archive/2007/10/15/925425.html
?
using?System;using?System.Net;
using?System.Net.Security;
using?System.Security.Cryptography.X509Certificates;
using?CallSslWebService.cxz;
namespace?CallSslWebService
{
????class?Program
????{
????????static?void?Main(string[]?args)
????????{
????????????try
????????????{
????????????????//掛接驗證服務端證書的回調
????????????????ServicePointManager.ServerCertificateValidationCallback?=?RemoteCertificateValidationCallback;?
????????????????cxz.Service?service?=?new?Service();?//實例一個web服務
????????????????//如果web服務沒有啟用匿名訪問,要聲明credentials
????????????????ICredentials?credentials?=?new?NetworkCredential("administrator",?"1234%^@");
????????????????service.Credentials?=?credentials;
????????????????
????????????????//如果服務器要求提供客戶端證書,下面代碼提供了客戶端證書
????????????????X509Certificate?cer?=?X509Certificate.CreateFromCertFile("C://certs//client.cer");
????????????????service.ClientCertificates.Add(cer);
????????????????//調用web服務
????????????????Console.WriteLine(service.HelloWorld());
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????Console.WriteLine(ex);
????????????}
????????????Console.Read();
????????}
????????public?static?bool?RemoteCertificateValidationCallback(Object?sender,
????????????X509Certificate?certificate,
????????????X509Chain?chain,
????????????SslPolicyErrors?sslPolicyErrors)
????????{
????????????//如果沒有錯就表示驗證成功
????????????if?(sslPolicyErrors?==?SslPolicyErrors.None)
????????????????return?true;
????????????return?false;
????????}
????}
}
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.chs/cpref10/html/T_System_Net_Security_SslStream_Members.htm
提供一個用于客戶端-服務器通信的流,此流使用安全套接字層 (SSL) 安全協議對服務器及客戶端(可選)進行身份驗證。
下表列出了由 SslStream 類型公開的成員。
轉載于:https://www.cnblogs.com/BinZeng/p/3373434.html
總結
以上是生活随笔為你收集整理的用TLS实现安全TCP传输及配置和访问https的web服务(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IOS开发 Block的学习
- 下一篇: linux 可执行文件与写操作的同步问题