在配置Windows Server 2012的远程桌面服务(RDS)时,可能会遇到与Windows Mobile 6.x或其他基于Windows CE 5.0的手持设备不兼容的问题。幸运的是,如果通过“Web Browser”方法激活了远程桌面许可服务器,只需要更改集合安全设置并禁用“仅允许...网络级别身份验证”(NLA)即可。以下内容同样适用于Windows 2008 R2终端服务器。检查是否通过“Web Browser”连接或直接激活许可服务器。2008 R2服务器作为独立服务器运行良好,适用于Windows Mobile,拥有100个许可证,并通过“Web Browser”激活。
让从头开始。基础RDS设置:当在现有或新的活动目录中安装Windows 2012服务器,然后添加远程桌面服务器角色时,有几个选择:
可以选择“基于场景的远程桌面服务安装”,然后选择“快速启动”后跟随向导。向导将把所有内容安装到一个服务器上。对于Windows Mobile客户端来说,虚拟桌面基础设施没有意义。他们不需要基于虚拟机的完整虚拟Windows机器。所以选择“会话虚拟化”。
然后向导将部署所有服务和角色,并创建一个默认的“会话集合”和“远程应用程序”。最后应该得到以下屏幕:
现在检查设置并查看RDS概览:
可以看到有RD Web Access(Windows Mobile未使用但无法移除),没有RD Gateway(这里不需要),没有RD Licensing(稍后将安装),RD Connection Broker,没有RD Virtualization Host(因为这里不提供虚拟机)和一个带有QuickSession Collection的RD Session Host。
在这个阶段,无法使用Windows Mobile客户端连接。NLA设置不允许,在远程桌面移动上得到一个错误。只需更改集合的NLA设置,Windows Mobile客户端就可以连接了。
注意,这里没有许可证服务器,处于RDS的120天试用中!
可以通过远程桌面服务-集合-CollectionName的TASKS菜单访问上述属性,并选择“编辑属性”。如果没有集合,无法更改设置!Windows桌面PC可以在没有安装集合的情况下连接到RDS。(Windows Mobile客户端)需要一个集合来禁用NLA。
设置远程桌面许可服务器:现在设置一个远程桌面许可服务器,激活它(或者更好的是,阅读稍后关于激活方法的注释:参见“RD许可证服务器激活连接方法”),并安装一些CALs或DALs(每个用户或设备的许可证)。确保许可证管理器显示许可证服务器没有任何错误。还要用RD许可证诊断器检查!
许可模式必须与一般集合属性设置相匹配:
如果一切都就绪并激活并许可,Windows Mobile客户端就无法再连接了!许可证服务器生成的证书与远程桌面移动不兼容。他们使用4096位密钥长度和SHA256足迹。证书存储在注册表中[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\RCM]。提取并转换这些证书看起来像这样:
证书:
数据:
版本:3(0x2)
序列号:0b:1c:04:1c:9c:74:34:af:41:3a:3c:bf:39:f5:56:bf
签名算法:sha256WithRSAEncryption
发行者:C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Assurance Designation Root 2011
有效期
不是之前:2011年3月23日17:41:27 GMT
不是之后:2036年3月23日17:48:11 GMT
主题:C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Assurance Designation Root 2011
主题公共密钥信息:
公钥算法:rsaEncryption
公钥:(4096位)
模数:
00:a8:ef:ce:ef:ec:12:8b:92:94:ed:cf:aa:a5:81:8d:4f:a4:ad:4a:ec:a5:f0:da:a8:3d:b6:e5:61:01
指数:65537(0x10001)
X509v3扩展:
X509v3密钥用法:
数字签名,证书签名,CRL签名
X509v3基本约束:关键
CA:TRUE
X509v3主题密钥标识符:
1A:A9:53:45:33:8E:D0:6E:22:52:54:76:39:76:43:1E:FF:79:14:41
签名算法:sha256WithRSAEncryption
0b:2e:fa:54:de:11:a4:72:e4:13:1d:8b:bc:42:36:7c:fe:76:
...
fa:be:02:5b:1a:c1:d9:58:66:c2:0c:b3:ce:e4:b4:ec:f4:eb:56:4f:9a:cc:cc:b2:a0:a4
RD许可证服务器激活连接方法
要修复这个问题并获得兼容的证书,请使用Web方法重新激活RD许可证服务器。在RD许可证管理器中右键单击服务器名称,然后选择属性。将连接方法更改为“Web Browser”。关闭属性并单击确定,然后再次右键单击服务器,然后高级-重新激活。按照重新激活服务器的Web浏览器过程。
重新激活后删除以下注册表键并重新启动服务器!
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\RCM
o 证书
o X509证书
o X509证书ID
o X509证书2
这些注册表键将在重新启动后以较低的安全性重建(另见)。惊喜,重新启动后远程桌面移动(Windows CE5,Windows Mobile6.x和Windows Embedded Handheld 6.5.3)可以连接!
如果提取并转换新的“Web-based”证书,会看到差异:
证书:
数据:
版本:3(0x2)
序列号:01:9d:e7:ca:8c:9a:66:80
签名算法:sha1WithRSA
发行者:L=\x00W\x002\x00K\x001\x002, CN=\x00W\x002\x00K\x001\x002\x00H\x00G\x00O
有效期
不是之前:1970年3月10日14:50:50 GMT
不是之后:2049年3月10日14:50:50 GMT
主题:L=\x00W\x002\x00K\x001\x002, CN=\x00W\x002\x00K\x001\x002\x00H\x00G\x00O
主题公共密钥信息:
公钥算法:rsaEncryption
公钥:(2048位)
模数:
00:b6:7e:f2:41:23:f1:f3:cf:44:90:e7:fc:ba:3f:
...
d0:51:d1:55:8c:6b:d0:f6:65:e5:c4:d2:09:1d:d0:17:c7
指数:65537(0x10001)
X509v3扩展:
X509v3基本约束:
CA:TRUE, pathlen:0
1.3.6.1.4.1.311.18.8:
Q.G.K.8.V.3.W.2.K.H.P.D.6.W.4.V.M.Q.2.G.3.T.H.3.K.C.8.J.W.K.W.D.M.4.Y...
签名算法:sha1WithRSA
3a:1d:94:36:5d:32:12:6f:5e:e3:76:9f:cb:2b:1c:92:c2:ff:
...
ac:1e:23:b2:a0:73:ff:6f:12:f8:86:24:4b:95:15:54:c0:a2:
ba:05:00:e3
密钥长度仅为2048位,安全算法为SHA1。如果在第一次激活服务器之前激活了“Web浏览器”连接方法,就不需要触摸注册表并重新激活服务器!
结论:Windows Mobile的远程桌面移动(RDM)应用程序在激活RD许可证服务器时生成正确的证书就可以很好地连接。如果服务器上使用SHA256和4096位密钥,RDM将无法连接。RDM不支持NLA或SSL/TLS!
测试安装:如果想检查安装证书,可以使用附带的演示应用程序:“RDS2012_security”。它将只读取注册表并显示证书数据。
代码(包含在附件中)只是读取注册表并提取证书数据。数据以二进制形式存储,开头有一些额外的数据。需要移除前12个字节以获得原始证书(所有这些证书都以0×30 0×82开头)。因此,注册表可能如下所示:
X509 Certificate=hex:02,00,00,00,04,00,00,00,f1,05,00,00,30,82,05,ed,30,82,\03,d5,a0,03,02,01,02,02,10,0b,1c,04,1c,9c,74,34,af,41,3a,3c,bf,39,f5,56,bf,30,0d,06,09,2a,86,48,86,f7,0d,01,01,0b,05,00,30,81,88,31,0b,30,09,06,03,55,...
然后该工具需要移除前12个字节,得到原始数据:
30,82,05,ed,30,82,\03,d5,a0,03,02,01,02,02,10,0b,1c,04,1c,9c,74,34,af,41,3a,3c,bf,39,f5,56,bf,30,0d,06,09,2a,86,48,86,f7,0d,01,01,0b,05,00,30,81,88,31,0b,30,09,06,03,55,...
以下是在csharp中执行此操作的简单代码,然后初始化一个新的X509Certificate2对象:
const string rd_mainRegKey = @"SYSTEM\CurrentControlSet\Control\Terminal Server\RCM";
string[] _x509ValueNames = new string[] {
"X509 Certificate",
"X509 Certificate2"
};
...
byte[] readX509Cert(string sValueName)
{
byte[] buf = null;
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(rd_mainRegKey, false))
{
byte[] bufTemp = (byte[])rk.GetValue(sValueName);
// remove first 12 bytes
buf = new byte[bufTemp.Length - 0x0b];
Array.Copy(bufTemp, 0x0c, buf, 0, bufTemp.Length - 0x0c);
}
if (sValueName.EndsWith("2"))
_x509Certificate2 = new X509Certificate2(buf);
else
_x509Certificate = new X509Certificate2(buf);
return buf;
}