本文转自:http://msdn.microsoft.com/zh-cn/library/windows/apps/jj150597.aspx
本主题将展示在使用 StreamSocket 功能时,如何使 Windows 应用商店应用可以保护 TLS/SSL 流套接字连接。
使用套接字和 WebSocket 启用网络通信。
安全套接字层 (SSL) 和最新的传输层安全 (TLS) 都是旨在为网络通信提供身份验证和加密功能的加密协议。这些协议专门用于在发送和接收网络数据时防止发生窃听和篡改。 这些协议使用一种客户端-服务器模型进行协议交换。这些协议还会使用数字证书和证书颁发机构来验证服务器是否与其自称的身份相符。TLS 协议记录在 IETF RFC 5246 中。 早期的 SSL 协议由 Netscape Communications 记录。 SSL 通常用于指这两种协议。
StreamSocket 对象可以配置用于在客户端和服务器之间使用 SSL/TLS 进行通信。对 SSL/TLS 的支持仅限于在 SSL/TLS 协商中将 StreamSocket 对象用作客户端。当系统接受一个连接以在被创建的 StreamSocket 上启用 SSL/TLS 时,由于作为服务器的 SSL/TLS 协商没有为 StreamSocket 实现,所以StreamSocketListener 现在不能使用 SSL/TLS 用于被创建的 StreamSocket。 SSL/TLS 的客户端支持不包括使用客户端证书的功能。
有以下两种方法可以借助 SSL/TLS 确保 StreamSocket 连接的安全:
建立与网络服务的初始连接并立即协商对所有通信使用 SSL/TLS。有两种 ConnectAsync 方法支持传递protectionLevel 参数:
如果 protectionLevel 参数被设置为 Windows.Networking.Sockets.SocketProtectionLevel.Ssl,当调用上述任一ConnectAsync 方法时,StreamSocket 必须使用 SSL/TLS 用于加密。此值需要加密而且绝不允许使用 NULL 密码。
一般来说,使用这些 ConnectAsync 方法的顺序都是相同的。
以下示例将会创建 StreamSocket,并尝试建立与网络服务的连接并立即协商使用 SSL/TLS。如果协商成功,则在客户端和网络服务器之间使用 StreamSocket 的所有网络通信都将被加密。
using Windows.Networking; using Windows.Networking.Sockets; // Define some variables and set values StreamSocket clientSocket = new StreamSocket(); HostName serverHost = new HostName("www.contoso.com"); string serverServiceName = "https"; // For simplicity, the sample omits implementation of the // NotifyUser method used to display status and error messages // Try to connect to contoso using HTTPS (port 443) try { // Call ConnectAsync method with SSL await clientSocket.ConnectAsync(serverHost, serverServiceName, SocketProtectionLevel.Ssl); NotifyUser("Connected"); } catch (Exception exception) { // If this is an unknown status it means that the error is fatal and retry will likely fail. if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) { throw; } NotifyUser("Connect failed with error: " + exception.Message); // Could retry the connection, but for this simple example // just close the socket. clientSocket.Dispose(); clientSocket = null; } // Add code to send and receive data using the clientSocket // and then close the clientSocket
先不加密建立与网络服务的初始连接。应用可以发送或接收数据。然后升级连接,对此后所有通信使用 SSL/TLS。使用如下方法:
UpgradeToSslAsync 方法有两个参数。protectionLevel 参数表示所需的保护级别。validationHostName 参数是在升级到 SSL 时用于进行验证的远程网络目标的主机名。 通常情况下,validationHostName 将是应用最初建立连接时所使用的相同主机名。如果 protectionLevel 参数被设置为 Windows.System.Socket.SocketProtectionLevel.Ssl,当调用上述任一 UpgradeToSslAsync 方法时,StreamSocket 必须使用 SSL/TLS 用于加密。此值需要加密而且绝不允许使用 NULL 密码。
一般来说,使用 UpgradeToSslAsync 方法的顺序都是:
以下示例将会创建 StreamSocket,并尝试建立与网络服务的连接、发送一些初始数据,然后协商使用 SSL/TLS。如果协商成功,则在客户端和网络服务器之间使用 StreamSocket 的所有网络通信都将被加密。
using Windows.Networking; using Windows.Networking.Sockets; using Windows.Storage.Streams; // Define some variables and set values StreamSocket clientSocket = new StreamSocket(); HostName serverHost = new HostName("www.contoso.com"); string serverServiceName = "http"; // For simplicity, the sample omits implementation of the // NotifyUser method used to display status and error messages // Try to connect to contoso using HTTP (port 80) try { // Call ConnectAsync method with a plain socket await clientSocket.ConnectAsync(serverHost, serverServiceName, SocketProtectionLevel.PlainSocket); NotifyUser("Connected"); } catch (Exception exception) { // If this is an unknown status it means that the error is fatal and retry will likely fail. if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) { throw; } NotifyUser("Connect failed with error: " + exception.Message, NotifyType.ErrorMessage); // Could retry the connection, but for this simple example // just close the socket. clientSocket.Dispose(); clientSocket = null; return; } // Now try to sent some data DataWriter writer = new DataWriter(clientSocket.OutputStream); string hello = "Hello World ? "; Int32 len = (int) writer.MeasureString(hello); // Gets the UTF-8 string length. writer.WriteInt32(len); writer.WriteString(hello); NotifyUser("Client: sending hello"); try { // Call StoreAsync method to store the hello message await writer.StoreAsync(); NotifyUser("Client: sent data"); writer.DetachStream(); // Detach stream, if not, DataWriter destructor will close it. } catch (Exception exception) { NotifyUser("Store failed with error: " + exception.Message); // Could retry the store, but for this simple example // just close the socket. clientSocket.Dispose(); clientSocket = null; return; } // Now upgrade the client to use SSL try { // Try to upgrade to SSL await clientSocket.UpgradeToSslAsync(SocketProtectionLevel.Ssl, serverHost); NotifyUser("Client: upgrade to SSL completed"); // Add code to send and receive data // The close clientSocket when done } catch (Exception exception) { // If this is an unknown status it means that the error is fatal and retry will likely fail. if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown) { throw; } NotifyUser("Upgrade to SSL failed with error: " + exception.Message); clientSocket.Dispose(); clientSocket = null; return; }
SocketProtectionLevel 枚举 有三个可能的值:
通常不使用 SslAllowNullEncryption 值,因为它允许使用 NULL 密码,这就意味着不加密,所以网络通信可能也不加密。SslAllowNullEncryption 值允许 SSL/TLS 协商,以根据服务器数字证书和证书颁发机构对服务器进行验证。
如果使用 SslAllowNullEncryption 值,那么实际上使用 ConnectAsync 或 UpgradeToSslAsync 协商得到的 SSL 强度可通过获取 StreamSocketinformation.ProtectionLevel 属性来确定。
[转]如何借助 TLS/SSL 确保套接字连接的安全(使用 C#/VB/C++ 和 XAML 的 Windows 应用商店应用),布布扣,bubuko.com
[转]如何借助 TLS/SSL 确保套接字连接的安全(使用 C#/VB/C++ 和 XAML 的 Windows 应用商店应用)
原文:http://www.cnblogs.com/freeliver54/p/3623257.html