网站收费模板,手机提取网页视频下载,哪个装修公司比较好,中国黄页免费版SSL(Security Socket Layer)是TLS(Transport Layer Security)的前身#xff0c;是一种加解密协议#xff0c;它提供了再网络上的安全传输#xff0c;它介于网络通信协议的传输层与应用层之间。 为实现TCP层之上的ssl通信#xff0c;需要用到数字证书。本文通过具体例子来说… SSL(Security Socket Layer)是TLS(Transport Layer Security)的前身是一种加解密协议它提供了再网络上的安全传输它介于网络通信协议的传输层与应用层之间。 为实现TCP层之上的ssl通信需要用到数字证书。本文通过具体例子来说明如何使用数字证书来实现网络上的安全传输。需要用到.net提供的SslStream, TcpListener, TcpClient, X509Certificate2,X509Store,X509Certification2Collection等类。终于开始涉及到代码了。 一.服务器端 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 else20 {21 return null;22 } 注意X509Certificate2构造函数第三个参数如果想把调用Export方法将cert对象到处此处必须使用Exportable标记否则在导出时会抛出异常。 pfx格式的证书包含有private key因此需要密码的保护构造函数的第二个参数就是密码。 选取的证书必须包含有private key否则在SSL的server端使用时会抛出AuthenticationException。 怎么得到pfx文件使用MMC-File-Add/Remove Sanp-in-Add-Certificates-Add-My user account/Computer account-Finish 查看存储在本机当前用户和所有用户的证书选择用导出的证书 右键-All Tasks...-Export...注意要勾选[Yes, export the private key]如果该Radio button被禁用说明该证书的private key不能被导出可能是在导入该证书时没有选择标记private key为可导出如下图所示 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监听 TCP监听 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.指定服务器证书 指定服务器证书 1 // A client has connected. Create the 2 // SslStream using the clients network stream. 3 SslStream sslStream new SslStream(client.GetStream(), false); 4 // Authenticate the server but dont 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.发送数据 1 byte[] message Encoding.UTF8.GetBytes(Hello from the server.EOF);2 sslStream.Write(message);3 sslStream.Flush(); 5.接收数据 接收数据 1 byte[] buffer new byte[2048]; 2 StringBuilder messageData new StringBuilder(); 3 int bytes -1; 4 do 5 { 6 // Read the clients 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后需要调用Flush将数据立刻发送Read需要多次调用确定读不到数据位置因为TCP连接时Stream方式的在网络中传输可能会分包到达一次无法全部读取还需要消息边界。 6.结束 1 sslStream.Close();2 client.Close(); 二.客户端 1.与服务器端建立TCP连接 1 TcpClient client new TcpClient(machineName, 8080); 2.与服务端建立SSL握手 客户端与服务端建立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 } 如果服务端在调用AuthenticateAsServer方法时指定不需要客户端的证书则客户端在调用AuthenticateAsClient时可以不指定证书 如果server在AuthenticateAsServer是指定client需要cert而client在调用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. Client在AuthenticateAsClient方法指定的名字需要与server端使用cert的名字一致否则在RemoteCertificateValidationCallback事件中SslPolicyErrors会是RemoteCertificateNameMismatch 3.发送接收数据关闭连接与服务器端方法相同 使用Wireshark Network Analyzer工具进行抓包分析发现在建立TCP连接后首先进行SSL握手之后传输的数据都是被加密的如下图所示 对SSL的握手和加密传输的详细过程将在下节分析。 下载Demo 转载于:https://www.cnblogs.com/piyeyong/archive/2010/06/20/1761458.html