本文转自:http://msdn.microsoft.com/zh-cn/library/windows/apps/jj150597.aspx

本主题将展示在使用 StreamSocket 功能时,如何使 Windows 应用商店应用可以保护 TLS/SSL 流套接字连接。

你需要了解的内容

技术

先决条件

  • 在本主题中,以下示例都来自 C# 和 C++。建议对套接字和 SSL/TLS 的使用有一个基本的了解。

SSL/TLS 连接概述

安全套接字层 (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 连接的安全:

  • ConnectAsync - 建立到网络服务的初始连接并立即协商对所有通信使用 SSL/TLS。
  • UpgradeToSslAsync - 先不加密连接到网络服务。应用可以发送或接收数据。然后升级连接,对此后所有通信使用 SSL/TLS。

使用 ConnectAsync

建立与网络服务的初始连接并立即协商对所有通信使用 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

使用 UpgradeToSslAsync

先不加密建立与网络服务的初始连接。应用可以发送或接收数据。然后升级连接,对此后所有通信使用 SSL/TLS。使用如下方法:

UpgradeToSslAsync 方法有两个参数。protectionLevel 参数表示所需的保护级别。validationHostName 参数是在升级到 SSL 时用于进行验证的远程网络目标的主机名。 通常情况下,validationHostName 将是应用最初建立连接时所使用的相同主机名。如果 protectionLevel 参数被设置为 Windows.System.Socket.SocketProtectionLevel.Ssl,当调用上述任一 UpgradeToSslAsync 方法时,StreamSocket 必须使用 SSL/TLS 用于加密。此值需要加密而且绝不允许使用 NULL 密码。

一般来说,使用 UpgradeToSslAsync 方法的顺序都是:

  • 创建一个 StreamSocket
  • 如果需要在套接字上使用高级选项,请使用 StreamSocket.Control 属性获取与 StreamSocket 对象 相关联的StreamSocketControl 实例。 针对 StreamSocketControl 设置一个属性。
  • 如果任何数据需要以不加密的形式进行发送和接收,则立即发送。
  • 调用 UpgradeToSslAsync 方法以启动将连接升级为使用 SSL/TLS。

以下示例将会创建 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 枚举 有三个可能的值:

  • PlainSocket - 一个未加密的纯套接字。
  • Ssl - 一个必须使用 SSL/TLS 进行加密的套接字。此值需要加密而且绝不允许使用 NULL 密码。
  • SslAllowNullEncryption - 一个首选使用 SSL/TLS 进行加密的套接字。该值首选使用完全加密,但允许基于服务器的配置使用 NULL 密码(即不加密)。

通常不使用 SslAllowNullEncryption 值,因为它允许使用 NULL 密码,这就意味着不加密,所以网络通信可能也不加密。SslAllowNullEncryption 值允许 SSL/TLS 协商,以根据服务器数字证书和证书颁发机构对服务器进行验证。

如果使用 SslAllowNullEncryption 值,那么实际上使用 ConnectAsync 或 UpgradeToSslAsync 协商得到的 SSL 强度可通过获取 StreamSocketinformation.ProtectionLevel 属性来确定。

相关主题

其他
使用套接字进行连接
使用套接字进行连接(使用 JavaScript 和 HTML 的 Windows 应用商店应用)
如何借助 TLS/SSL 确保套接字连接的安全(使用 JavaScript 和 HTML 的 Windows 应用商店应用)
如何使用高级套接字控件
快速入门:使用流套接字进行连接
参考
SocketProtectionLevel
StreamSocket
StreamSocket.ConnectAsync
StreamSocket.UpgradeToSslAsync
StreamSocketinformation.ProtectionLevel
Windows.Networking.Sockets

[转]如何借助 TLS/SSL 确保套接字连接的安全(使用 C#/VB/C++ 和 XAML 的 Windows 应用商店应用)的更多相关文章

  1. fsockopen — 打开一个网络连接或者一个Unix套接字连接

    fsockopen (PHP 4, PHP 5, PHP 7) 说明 resource fsockopen ( string $hostname [, int $port = -1 [, int &a ...

  2. Linux/UNIX套接字连接

    套接字连接 套接字是一种通信机子.凭借这样的机制.客户/server系统的开发工作既能够在本地单机上进行.也能够夸网络进行. 套接字的创建和使用与管道是有差别的.由于套接字明白地将客户和server区 ...

  3. WCF 套接字连接已中止。这可能是由于处理消息时出错或远程主机超过接收超时或者潜在的网络资源问题导致的

    一个项目需要用到推送的功能,就是服务器主动推送数据给多台客户机.于是采用了WCF的双工通讯netTcpBinding 写好的项目,在本机测试都没有问题. 如果放在局域网内测试,问题出来了:先是安全性问 ...

  4. 解决VMware虚拟机报错“无法连接MKS:套接字连接尝试次数太多,正在放弃”

    1.错误描述 在VMware中打开虚拟机时报错: "无法连接MKS:套接字连接尝试次数太多,正在放弃" 物理机操作系统: Windows 7 虚拟机操作系统: Kali Linux ...

  5. Linux:【解决】无法连接 MKS:套接字连接尝试次数太多正在放弃

    [解决]无法连接 MKS:套接字连接尝试次数太多正在放弃 操作: 我的电脑 -> 右键 -> 管理 -> 服务和应用程序 -> 服务: 开启下面的服务: ​ 服务启动成功后,重 ...

  6. PHP Socket(套接字连接)扩展简介和使用方法

    PHP socket扩展是基于流行的BSD sockets,实现了和socket通讯功能的底层接口,它可以和客户端一样当做一个socket服务器. 使用这些函数时请注意,虽然他们中有很多和C函数同名的 ...

  7. VMware Workstation “无法连接 MKS: 套接字连接尝试次数太多;正在放弃。” 解决方法【转】

    今天和往常一样打开电脑,打开VMware Workstation,打开其中的一台虚拟机,以前都是这么打开没有问题,今天打开虚拟机突然提示“无法连接 MKS: 套接字连接尝试次数太多:正在放弃.”. 经 ...

  8. Vmware Pro 14报错:无法连接 MKS: 套接字连接尝试次数太多;正在放弃。

    软件环境: 虚拟机软件:VMware Pro 14 母机操作系统:win7 客户机操作系统:CentOS 7     问题详情: 报错:无法连接 MKS: 套接字连接尝试次数太多:正在放弃.     ...

  9. VMware无法连接MKS:套接字连接尝试次数太多解决

    粘贴自:https://jingyan.baidu.com/article/425e69e61eb578be15fc16ae.html VMware在开启虚拟机的时候,突然弹出[无法连接MKS:套接字 ...

随机推荐

  1. 【03】AngularJS 简介

    AngularJS 简介 AngularJS 是一个 JavaScript 框架.它可通过 <script> 标签添加到 HTML 页面. AngularJS 通过 指令 扩展了 HTML ...

  2. cocos2d 接 android sdk 的一个小坑 关于armbeabi 和 armbeabi-v7a

    cocos2d 接 android sdk 的时候,有些sdk会要求外链到某个工程中,而这个工程的lib文件夹里会包含armbeabi 和 armbeabi-v7a这两个文件夹,如果直接打包会闪退.只 ...

  3. HDU 482 String

    String Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 482 ...

  4. C语言编程规范试题

    C语言编程规范试题 [说明]: 1.本试题中不考虑头文件引用问题(假定已经包含正确的头文件),C语言的标准函数都可用: 2.如果不特别说明,假定程序运行环境为:操作系统Windows 2000, VC ...

  5. FFT模板(From MG)

    #include<cstdio> #include<cmath> #include<algorithm> using namespace std; struct c ...

  6. 【Teamviewer】Teamviewer远程访问工具使用方法

    首先电脑必须能访问外网,即使是在局域网内也无所谓. 1.这里以非自动登录.自动受控的方式为例.首先,让对方也安装一个Teamviewer,或运行一个绿色的Teamviewer,并保证网络可通.然后我们 ...

  7. J - A Bug's Life 并查集

    Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes ...

  8. 创建NetCore2.2 Web项目+EFCore+SQLServer

    在空余时间学习下NetCore,记录日常,供参考. 1.确保已下载安装NetCore2.2SDK 环境,下载地址:https://dotnet.microsoft.com/download/dotne ...

  9. hp 1810-24g switch reset

    Specific steps to execute the factory default reset on the switch are: 1. Using a small, thin tool w ...

  10. 使用Code First建模自引用关系笔记 asp.net core上使用redis探索(1) asp.net mvc控制器激活全分析 语言入门必学的基础知识你还记得么? 反射

    使用Code First建模自引用关系笔记   原文链接 一.Has方法: A.HasRequired(a => a.B); HasOptional:前者包含后者一个实例或者为null HasR ...