具有 SmartCard 认证的 WCF 客户端适用于 Win7,但不适用于 XP [英] WCF client with SmartCard certification works on Win7, but not on XP

查看:26
本文介绍了具有 SmartCard 认证的 WCF 客户端适用于 Win7,但不适用于 XP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是简要总结:我有一个 WCF 客户端 (.NET 4.0),它在 Windows 7(64 位)上运行良好,但在 XP(32 位)上运行失败.因为我有很多 XP 客户,所以这是个大问题.

  • 客户端由服务提供商提供的 wsdl 文件生成.
  • 服务是基于 SSL 的 SOAP 1.2,带有 MTOM
  • 客户端证书位于智能卡 (ActivIdentity) 上

代码如下:

 ServicePointManager.ServerCertificateValidationCallback = delegate { return true;};//System.Net.ServicePointManager.SecurityProtocol =System.Net.SecurityProtocolType.Tls;//.Ssl3;EndpointAddress addr = new EndpointAddress(g2bservice);B2GServiceClient 客户端 = 新 B2GServiceClient(NCTSBinding.Create(), addr);client.ClientCredentials.ClientCertificate.Certificate = ccer;//智能卡上的一个client.Endpoint.Behaviors.Add(new MyCustomBehavior());回声 e = 新回声();e.Msg = "你好,世界!";echoResponse r = client.echo(e);

这个绑定是这样创建的:

 BindingElement[] be = new BindingElement[2];be[0] = 新的 NCTSMessageEncodingBindingElement();HttpsTransportBindingElement hbe = new HttpsTransportBindingElement();hbe.RequireClientCertificate = true;be[1] = hbe;CustomBinding _b = new CustomBinding(be);返回_b;

其中 NCTSMessageEncodingBinding 与 MtomMessageEncodingBinding 相同,但覆盖了 IsContentTypeSupported(...).

因此,此代码可在 Win7 上运行,并带有对话框,要求输入 PIN 以从智能卡中获取私有部分".在 XP 上,从不发出输入 PIN 的对话框,而是出现错误消息:

"向 https://cistest.apis-it.hr:8446/g2bservis 发出 HTTP 请求时发生错误.这可能是由于服务器证书没有正确配置 HTTP.HTTPS 情况下为 SYS.这也可能是由于客户端和服务器之间的安全绑定不匹配造成的."

请问有什么线索吗?XP和Win7在支持基础设施上有什么区别?

小更新:请注意工作和非工作跟踪日志中不同的粗体线.出于某种原因,在 Windows 7 机器上,初始消息在消息中包含服务名称 (cistest.apis-it.hr),而在 XP 上则缺少此信息.此消息后,XP 上的套接字已关闭...

<前>Windows 7,工作示例(相同代码):System.Net 信息:0:[3748] SecureChannel#23960260 - 证书的类型为 X509Certificate2 并包含私钥.System.Net 信息:0:[3748] AcquireCredentialsHandle(包 = Microsoft 统一安全协议提供程序,意图 = 出站,scc = System.Net.SecureCredential)System.Net 信息:0:[3748] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = (null), targetName = cistest.apis-it.hr, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)System.Net 信息:0:[3748] InitializeSecurityContext(缓冲区内长度=0,缓冲区外长度=122,返回代码=ContinueNeeded).System.Net.Sockets 详细:0:[3748] Socket#46340781::Send()System.Net.Sockets Verbose: 0 : [3748] 来自 Socket#46340781::Send 的数据System.Net.Sockets 详细: 0 : [3748] 00000000 : 16 03 01 00 75 01 00 00-71 03 01 4E 67 4E 6A 26 : ....u...q..NgNj&System.Net.Sockets 详细:0:[3748] 00000010:C6 C9 65 17 D7 EC C1 A1-15 72 E1 56 80 F4 5A BB:..e......r.V..Z.System.Net.Sockets 详细:0:[3748] 00000020:A8 4C 50 54 84 D4 3E 86-29 68 CA 00 00 18 00 2F:.LPT..>.)h.../System.Net.Sockets 详细: 0 : [3748] 00000030 : 00 35 00 05 00 0A C0 13-C0 14 C0 09 C0 0A 00 32 : .5................2System.Net.Sockets 详细:0:[3748] 00000040:00 38 00 13 00 04 01 00-00 30 FF 01 00 01 00 00:.8.......0......System.Net.Sockets 详细:0:[3748] 00000050:00 00 17 00 15 00 00 12-63 69 73 74 65 73 74 2E:........cistest.System.Net.Sockets 详细:0:[3748] 00000060:61 70 69 73 2D 69 74 2E-68 72 00 0A 00 06 00 04:apis-it.hr......System.Net.Sockets 详细:0:[3748] 00000070:00 17 00 18 00 0B 00 02-01 00:........System.Net.Sockets Verbose: 0 : [3748] 退出 Socket#46340781::Send() -> 122#122XP,不工作的例子(相同的代码):System.Net 信息:0:[2272] SecureChannel#7307181 - 证书的类型为 X509Certificate2 并包含私钥.System.Net 信息:0:[2272] AcquireCredentialsHandle(包 = Microsoft 统一安全协议提供程序,意图 = 出站,scc = System.Net.SecureCredential)System.Net 信息:0:[2272] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = (null), targetName = cistest.apis-it.hr, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)System.Net 信息:0:[2272] InitializeSecurityContext(缓冲区内长度=0,缓冲区外长度=77,返回代码=ContinueNeeded).System.Net.Sockets 详细:0:[2272] Socket#32308990::Send()System.Net.Sockets Verbose: 0 : [2272] 来自 Socket#32308990::Send 的数据System.Net.Sockets 详细: 0 : [2272] 00000000 : 16 03 01 00 48 01 00 00-44 03 01 4E 67 4E 1E C1 : ....H...D..NgN..System.Net.Sockets 详细: 0 : [2272] 00000010 : 32 BD E0 57 87 A8 68 8B-32 77 00 18 DE 3F 69 3D : 2..W..h.2w...?i=System.Net.Sockets 详细:0:[2272] 00000020:D7 B1 7B 76 AD 26 A6 63-6B BB 49 00 00 16 00 04:..{v.&.ck.I.....System.Net.Sockets 详细:0:[2272] 00000030:00 05 00 0A 00 09 00 64-00 62 00 03 00 06 00 13:.......d.b......System.Net.Sockets 详细: 0 : [2272] 00000040 : 00 12 00 63 01 00 00 05-FF 01 00 01 00 : ...c ....System.Net.Sockets Verbose: 0 : [2272] 退出 Socket#32308990::Send() -> 77#77System.Net.Sockets 详细:0:[2272] Socket#32308990::Receive()System.Net.Sockets Verbose: 0 : [2272] 来自 Socket#32308990::Receive 的数据System.Net.Sockets 详细: 0 : [2272] 00000000 : 15 03 01 00 02 : ........System.Net.Sockets Verbose: 0 : [2272] 退出 Socket#32308990::Receive() -> 5#5System.Net.Sockets 详细:0:[2272] Socket#32308990::Receive()System.Net.Sockets Verbose: 0 : [2272] 来自 Socket#32308990::Receive 的数据System.Net.Sockets 详细: 0 : [2272] 00000005 : 02 28 : .(System.Net.Sockets Verbose: 0 : [2272] 退出 Socket#32308990::Receive() -> 2#2System.Net.Sockets 详细:0:[2272] Socket#32308990::Receive()System.Net.Sockets Verbose: 0 : [2272] 来自 Socket#32308990::Receive 的数据System.Net.Sockets 详细:0:[2272] 00000007::System.Net.Sockets Verbose: 0 : [2272] 退出 Socket#32308990::Receive() -> 0#0System.Net.Sockets 详细:0:[2272] Socket#32308990::Dispose()

解决方案

嗯,在尝试解决这个问题一个月左右后,结论是这个问题无法解决.至少它无法通过本机 .NET 和操作系统支持来解决.对于 Microsoft 而言,Windows XP 显然太旧了,无法支持 AES 256 位加密、使用 RSA 进行 SHA 256 位签名以进行密钥交换.世界上有 40% 的用户还在使用 XP,所以这个决定真的很奇怪.

此类支持已添加到 Windows server 2003(我尝试添加 schannel.dll和 rsaenh.dll 从 2003 到 XP,有一些进步,但远非理想).

官方高级技术支持的回答是:目前情况看起来不太乐观,过去曾有其他客户要求获得 KB 文章的 XP 版本948963,但是这个请求被我们的产品组拒绝了.这些安全功能是在 Vista 中引入的,两个平台之间 6-7 年的差异使得它很难对 XP 进行更改."

因此,对于 SOAP 和 WebServices,我推荐 .NET,至少对于您不能控制双方的企业服务来说.

叹息!

Here is the brief summary: I have a WCF client (.NET 4.0) that behaves well on windows 7 (64 bit), but fails on XP (32 bit). Since I have a lot of XP customers, this is a huge problem.

  • client is generated from the wsdl file supplied by a service provider.
  • service is SOAP 1.2 over SSL, with MTOM
  • client certificates are on Smart Card (ActivIdentity)

Here is the code:

        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
        //System.Net.ServicePointManager.SecurityProtocol =System.Net.SecurityProtocolType.Tls;//.Ssl3;

        EndpointAddress addr = new EndpointAddress(g2bservice);
        B2GServiceClient client = new B2GServiceClient(NCTSBinding.Create(), addr);

        client.ClientCredentials.ClientCertificate.Certificate = ccer;  // one that is on SmartCard
        client.Endpoint.Behaviors.Add(new MyCustomBehavior());

        echo e = new echo();
        e.Msg = "Hello, World!";

        echoResponse r = client.echo(e);

and this binding is created like this:

        BindingElement[] be = new BindingElement[2];
        be[0] = new NCTSMessageEncodingBindingElement();
        HttpsTransportBindingElement hbe = new HttpsTransportBindingElement();
        hbe.RequireClientCertificate = true;
        be[1] = hbe;
        CustomBinding _b = new CustomBinding(be);
        return _b;

where NCTSMessageEncodingBinding is more-less the same as MtomMessageEncodingBinding with overriden IsContentTypeSupported(...).

So, this code works on Win7, with dialog asking for PIN to get "private parts" from smart card. On XP, dialog for entering PIN is never issued, there is an error message instead:

"An error occurred while making the HTTP request to https://cistest.apis-it.hr:8446/g2bservis. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server."

Any clues, please? What are the differences in the supporting infrastructure between XP and Win7?

Little update: please note bolded lines that differ in working and non working trace log. For some reason, on the windows 7 machine initial message contains service name (cistest.apis-it.hr) in the message, whilst on XP this info is missing. After this message, socket on XP is closed...

Windows 7, working example (same code):
System.Net Information: 0 : [3748] SecureChannel#23960260 - Certificate is of type X509Certificate2 and contains the private key.
System.Net Information: 0 : [3748] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent  = Outbound, scc     = System.Net.SecureCredential)
System.Net Information: 0 : [3748] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = (null), targetName = cistest.apis-it.hr, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [3748] InitializeSecurityContext(In-Buffer length=0, Out-Buffer length=122, returned code=ContinueNeeded).
System.Net.Sockets Verbose: 0 : [3748] Socket#46340781::Send()
System.Net.Sockets Verbose: 0 : [3748] Data from Socket#46340781::Send
System.Net.Sockets Verbose: 0 : [3748] 00000000 : 16 03 01 00 75 01 00 00-71 03 01 4E 67 4E 6A 26 : ....u...q..NgNj&
System.Net.Sockets Verbose: 0 : [3748] 00000010 : C6 C9 65 17 D7 EC C1 A1-15 72 E1 56 80 F4 5A BB : ..e......r.V..Z.
System.Net.Sockets Verbose: 0 : [3748] 00000020 : A8 4C 50 54 84 D4 3E 86-29 68 CA 00 00 18 00 2F : .LPT..>.)h...../
System.Net.Sockets Verbose: 0 : [3748] 00000030 : 00 35 00 05 00 0A C0 13-C0 14 C0 09 C0 0A 00 32 : .5.............2
System.Net.Sockets Verbose: 0 : [3748] 00000040 : 00 38 00 13 00 04 01 00-00 30 FF 01 00 01 00 00 : .8.......0......
System.Net.Sockets Verbose: 0 : [3748] 00000050 : 00 00 17 00 15 00 00 12-63 69 73 74 65 73 74 2E : ........cistest.
System.Net.Sockets Verbose: 0 : [3748] 00000060 : 61 70 69 73 2D 69 74 2E-68 72 00 0A 00 06 00 04 : apis-it.hr......
System.Net.Sockets Verbose: 0 : [3748] 00000070 : 00 17 00 18 00 0B 00 02-01 00                   : ..........
System.Net.Sockets Verbose: 0 : [3748] Exiting Socket#46340781::Send()  -> 122#122

XP, not working example (same code):
System.Net Information: 0 : [2272] SecureChannel#7307181 - Certificate is of type X509Certificate2 and contains the private key.
System.Net Information: 0 : [2272] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent  = Outbound, scc     = System.Net.SecureCredential)
System.Net Information: 0 : [2272] InitializeSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = (null), targetName = cistest.apis-it.hr, inFlags = ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitManualCredValidation)
System.Net Information: 0 : [2272] InitializeSecurityContext(In-Buffer length=0, Out-Buffer length=77, returned code=ContinueNeeded).
System.Net.Sockets Verbose: 0 : [2272] Socket#32308990::Send()
System.Net.Sockets Verbose: 0 : [2272] Data from Socket#32308990::Send
System.Net.Sockets Verbose: 0 : [2272] 00000000 : 16 03 01 00 48 01 00 00-44 03 01 4E 67 4E 1E C1 : ....H...D..NgN..
System.Net.Sockets Verbose: 0 : [2272] 00000010 : 32 BD E0 57 87 A8 68 8B-32 77 00 18 DE 3F 69 3D : 2..W..h.2w...?i=
System.Net.Sockets Verbose: 0 : [2272] 00000020 : D7 B1 7B 76 AD 26 A6 63-6B BB 49 00 00 16 00 04 : ..{v.&.ck.I.....
System.Net.Sockets Verbose: 0 : [2272] 00000030 : 00 05 00 0A 00 09 00 64-00 62 00 03 00 06 00 13 : .......d.b......
System.Net.Sockets Verbose: 0 : [2272] 00000040 : 00 12 00 63 01 00 00 05-FF 01 00 01 00          : ...c.........
System.Net.Sockets Verbose: 0 : [2272] Exiting Socket#32308990::Send()  -> 77#77
System.Net.Sockets Verbose: 0 : [2272] Socket#32308990::Receive()
System.Net.Sockets Verbose: 0 : [2272] Data from Socket#32308990::Receive
System.Net.Sockets Verbose: 0 : [2272] 00000000 : 15 03 01 00 02                                  : .....
...
System.Net.Sockets Verbose: 0 : [2272] Exiting Socket#32308990::Receive()   -> 5#5
System.Net.Sockets Verbose: 0 : [2272] Socket#32308990::Receive()
System.Net.Sockets Verbose: 0 : [2272] Data from Socket#32308990::Receive
System.Net.Sockets Verbose: 0 : [2272] 00000005 : 02 28                                           : .(
System.Net.Sockets Verbose: 0 : [2272] Exiting Socket#32308990::Receive()   -> 2#2
System.Net.Sockets Verbose: 0 : [2272] Socket#32308990::Receive()
System.Net.Sockets Verbose: 0 : [2272] Data from Socket#32308990::Receive
System.Net.Sockets Verbose: 0 : [2272] 00000007 :                                                 : 
System.Net.Sockets Verbose: 0 : [2272] Exiting Socket#32308990::Receive()   -> 0#0
System.Net.Sockets Verbose: 0 : [2272] Socket#32308990::Dispose()

解决方案

Well, after a month or so trying to solve this issue, the conclusion is that THIS ISSUE CANNOT BE SOLVED. At least it cannot be solved with native .NET and OS support. Windows XP is apparently too old for the Microsoft to support AES 256 bit encryption, SHA 256 bit signing with RSA for key exchange. There are 40% of users in the world still using XP, so this decision is really strange.

Such support is added into Windows server 2003 (I've tried to add schannel.dll and rsaenh.dll from 2003 to XP, some progress but far from ideal).

Official premium tech support answer was: "Currently the situation looks not promising, there was in the past a request from another customer to have an XP version of KB article 948963, however this request was rejected by our Product group. These security features were introduced in Vista and the 6-7 years difference between the two platforms make it hard to make that change to XP."

So, for the SOAP and WebServices, I would NOT recommend .NET, at least not for enterprise services where you don't control both sides.

Sigh!

这篇关于具有 SmartCard 认证的 WCF 客户端适用于 Win7,但不适用于 XP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆