如何确保只有定义良好的客户端与Web服务(WCF)进行通信? [英] How to ensure that only a well defined client talks to a Web service (WCF)?

查看:74
本文介绍了如何确保只有定义良好的客户端与Web服务(WCF)进行通信?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,



我需要开发客户端/服务器架构:



- 语言c#

- 原生客户

- 服务器:网络服务,可能是wcf服务



最大的挑战是确保只有我们的客户端软件可以与Web服务通话(发送数据)。

我用数字证书和其他一些东西来保护客户端本身,因此无法修改。但是如何确保没有人捕获网络流量然后将伪造的数据发送到服务。 SSL是不可能的。

我可以使用数字证书(Microsoft代码签名证书)中的公钥在发送之前加密数据吗?但如果是这样,其他人也可以使用这个公钥将加密数据发送到服务。



对于这个问题,什么是正确的(一个好的)解决方案?



谢谢。



Thom

解决方案

< blockquote>

第1部分





绝对可以。这很明显,但该方法的逻辑证明需要付出努力。



首先,让我们做我们的假设。我不能接受其中的一些 - 我有一个计划B。

首先,我们需要考虑三方:服务 S ,客户 C 和中间人 M ; Middleman能够监视 C S 之间的所有通信。显然,只有当 C M 有某些好处时, M 才能冒充 C 。没有打破泛化水平,让我们假设这个好处是某些关键 C 在其部署基础上接收用户身份验证。客户端的完整源代码可以打开,只有一个密钥是秘密的。



现在,让我假设你知道为所有客户部署密钥的方法通过互联网(没有SSL)的方式 M 无法获得此密钥,即使它一直在窥探。我认为因为这是一个众所周知的方法。我不确定是否可能,请阅读: http://en.wikipedia.org/wiki/RSA [ ^ ]。如果您还不相信,我会根据您的要求解释。



现在,我将对通信方法做最简单的假设。 1)它应该是基于会话的非安全协议(HTML或TCP),2)会话分为两部分:认证后跟信任;在认证过程中,客户端和服务交换消息用于证明客户端的真实性;在此之后,客户端被认为是可信任的,并且在没有任何加密的情您不需要秘密数据通信,只需要客户端的真实性。如果这两个假设不合适,我可以在进一步请求时讨论计划B。



现在,让我们使用相同的RSA并创建两个密钥。进一步的推测意味着保持该方法与RSA一样强。 RSA在.NET中实现。让我们按照步骤进行操作。



1)使用RSA密钥生成函数生成两个密钥 RSA => (K s ,K d )。

该函数没有后门:无法计算一个密钥基于知识或其他关键。我将 K s 称为加密密钥, K d - 解密密钥:< br $> b $ b



(未加密数据,K s ) - > (加密数据)

(加密数据,K d ) - > (未加密的数据)





2)让我们部署 K d C

在此步骤中, S K s 并且 K d C 只有 K d M 没有钥匙或数据。



3) S 启动,听取连接, C 连接, S 接受(新)连接。



4)会话协议的身份验证部分已启动。 S 生成身份验证令牌 T u (未加密)并将其加密为受限制的令牌 T u

(T u ,K s ) - > T s ,并将其发送到连接的客户端 C 。每个新会话都会随机生成新 T u



5) C 使用 K s 解密 T s

(T s ,K u ) - > T u



6) C 发送T u 公开地回到 S S 将其值与发送到 C 之前存储的值进行比较。这产生了 C 的证据。协议的可信部分开始。



7)此时 M 同时 T s T u 。它不能用于模拟 C ,因为它需要连接才能创建新会话;但对于这个新会话,身份验证令牌将是新的, M 不知道。此外,由于没有RSA后门, M 无法从数据中获取任何密钥。



如果有原因关于从 C S 公开发送 T u ,这部分也可以有计划B基于额外的一对密钥(其中一个密钥将是开放的并且 M 已知,以使这部分通信成为 M 的秘密。



就是这样。有任何问题,还有其他问题吗?



-SA


我自己找到了解决方案的一部分,所以我把它作为答案发布在这里。



我将使用客户端证书进行身份验证。



我必须将'Client Credential Type'设置为Certificate。我还发现了如何使用文件中的证书而不是来自注册表:使用证书进行WCF安全的简便方法 [ ^ ]



但是又有两个问题:

1.

我可以使用已经可用的代码签名证书吗?我想不是因为客户需要证书的私钥,这是我不会给出的。



2.

如何确保没有其他程序使用我的证书来识别服务器服务?我需要将证书复制到客户端计算机,因此,每个人都可以使用它(或者只是将其发布在inet中以供每个人使用)。我知道我可以使用密码保护证书,但是这个密码必须在我的exe内部才可以反编译。



什么是完整的解决方案?



谢谢

Thom


第2部分





这是一个基于问题澄清的答案。以前的答案被命名为第1部分,这一部分将是第2部分。

第1部分中的答案仍然有效,但它基于可信渠道分发软件证书的假设可以创建。初始要求(无SSL等)仅与已部署客户端软件时的服务和客户端运行时间相关;对部署机制没有限制。



根据澄清,客户端软件可以免费分发给一些匿名客户端,因此无法分发任何信息来自第三方的秘密,这打开了伪造客户端软件的可能性,该客户端软件具有修改的行为,可以模仿合法客户端软件可以通过的相同认证过程。怎么可能? 1)在验证令牌交换期间监视网络包是没用的,因为这些数据包只使用一次(参见第1部分),2)不可能修改保留其数字签名的原始客户端软件,因为程序集可以是已签名,私钥仅存储在软件团队中。不过,可以在调试器下运行客户端软件并在解密认证令牌之前捕获 K u 键。



这导致了一个我不太喜欢的明显解决方案。客户端软件应该使用功能强大的软件保护工具之一进行保护,特别是无法进行代码分析和调试(我有使用XHEO Code Veil的经验,http://xheo.com/products/code-protection )。问题是强大的解决方案是专有的。真正的问题甚至不是许可证和特许权使用费,这可能是相当大的,但缺乏评估保护力度和公司索赔有效性的机会。这将原则上解决问题,但同样,它并不能让我满意。



不幸的是,这是修改客户端软件时的固有问题是免费分发的,并且修改后的客户行为的可能性存在威胁。我已经表达了我的担忧:这可以被认为是更大的架构问题,一般数据模型的脆弱性。但是,我清楚地意识到重新思考这个模型是不可行的。



第3部分




具有软件保护的模式(第2部分)实际上是与第1部分的组合,即计划B。我认为问题需要一种截然不同的方法,计划C。它不应该要求架构中的全局更改,并且位于服务和客户端之间的瘦通信层中。



我的想法是将所有业务逻辑从客户端部分移动到服务,无法修改的地方。这是对架构的相对较小的修改。可以有不同的方法。



一种显而易见的方法是将应用程序转换为ASP.NET层,以表示服务和客户端之间的完整通信层。这是非常可行的。由于HTTP协议的限制,潜在的问题是客户端功能发生了重大变化。



替代方法是继续使用通过传输协议工作的常规UI客户端,但是从业务逻辑中清除,该业务逻辑被移至服务部分对应部分。这里我有一些初步的模式,需要一些额外的思考。



-SA


Hi all,

I need to develop a client/server architecture:

- language c#
- native client
- server: web service, may be wcf service

The biggest challenge ist to ensure, that only our client software can talk (send data) to the web service.
I protect the client itself with a digital certificate and some other things so it can't be modified. But how to make sure that nobody captures the network traffic and then sends faked data to the service. SSL is not possible.
Can I use the public key from the digital certificate (Microsoft Code Signing certificate) to encrypt the data before sending? But if so, someone else could also use this public key to send encrypted data to the service.

What would be the right (a good) solution for that problem?

Thanks.

Thom

解决方案

Part 1



This is absolutely possible. This is quite apparent, but logical proof of the method needs effort.

First, let's do our assumptions. I you cannot accept some of them — I have a plan "B".
First, we need to consider three parties: Service S, Client C and "Middleman" M; Middleman is able to spy on all communications between C and S. Apparently, M would not be able to impersonate C only if C has certain "benefit" over M. Not breaking the level of generalization, let's assume that the benefit is certain key C receives in its deployment bases on user authentication. The full source code of client can be open, only a key is secret.

Now, let me assume you know the method of deployment of the key to all clients even over Internet (without SSL) the way M cannot get this key even it it spies all the time. I assume that because this is a well-known method. I you're not sure it's possible, read this: http://en.wikipedia.org/wiki/RSA[^]. If your not convinced yet, I'll explain that on you request.

Now, I'm going to do the easiest assumptions on communication method. 1) It should be session-based non-secure protocol (HTML or TCP), 2) The session is divided in two parts: authentication followed by trusted; during authentication part client and service exchange messages used to proof authenticity of the client; after that, client is considered trusted and further work is done without any encryption. You did not require secret data communication, only authenticity of the client. If these two assumption are not OK, I can discuss plan "B" on further request.

Now, let's use same very RSA and create two keys. Further speculations are meant to maintain that the method is as strong as RSA. RSA is implemented in .NET. Let's follow the steps.

1) Generate two keys using RSA key generation function RSA => (Ks, Kd).
The function has no "backdoor": it is not possible to calculate one key base on knowledge or another key. I'll call Ks a "encrypting" key, Kd — a "decrypting" key:


(unencrypted data, Ks) —> (encrypted data)
(encrypted data, Kd) —> (unencrypted data)


2) Let's deploy Kd with C.
At this step, S has Ks and Kd, C has only Kd, M has not keys or data.

3) S starts, listen to connections, C connects, S accept (new) connection.

4) Authentication part of session protocol started. S generates "Authentication Token" Tu (unencrypted) and encrypt it into encrtypted token Tu:
(Tu, Ks) —> Ts, and sends it to a connected client C. New Tu is generated randomly for every new session.

5) C use Ks to decrypt Ts:
(Ts, Ku) —> Tu.

6) C sends Tu back to S openly, S compares its values with the value stored before sending it to C. That creates an evidence of C. Trusted part of protocol starts.

7) At this point M has both Ts and Tu. It cannot be used for impersonation of C, because it would require to connect to create a new session; but for this new session Authentication Token will be new, not known to M. Also, as there is no RSA "back door", M cannot obtain any of the keys from data.

If there is a reason to concern about open sending of Tu from C to S, this part also can have plan "B" based on additional pair of keys (one of them will be open and known to M to make this part of communication a secret from M.

That's it. Any concerns, further questions?

—SA


I found a part of the solution by myself so I post it here as answer.

I've to use a client certificate for Authentication.

I have to set the 'Client Credential Type' to Certificate. I also found how to use a certificate from a file and not from registry: An easy way to use certificates for WCF security[^]

But again there are 2 questions open:
1.
Can I use for this also the already available code signing certificate? I think not because the client needs the private key of the certificate and this is something I will not give out.

2.
How do I make sure that no other program uses my certficate to identify itself against the server service? I need to copy the certificate to the client computer and so, everyone could use it (or simply post it in the inet for everybodies use). I know I can protect the certificate with a password but this password must be then inside my exe which can be decompiled.

What is the complete solution?

Thanks
Thom


Part 2



This is a different Answer based on clarification of the problem. Previous Answer is named as "Part 1", this one will be "Part 2".
The Answer in Part 1 remains valid, but it's based on the assumption that a trusted channel for distribution of software certificate can be created. Initial requirements (no SSL, etc.) are related only to the Service and Client run time when client software is already deployed; there were no limitation on the mechanism of deployment.

According to the clarification, Client software is freely distributed to some anonymous clients, so there is no way to distribute any information secret from third party, which opens the possibility to forge Client software with modified behavior which could mimic the same authentication procedure a legitimate Client software can pass. How that is possible? 1) It is useless to spy on network package during exchange of Authentication Token, because these packets are used only once (see Part 1), 2) it is not possible to modify original Client software keeping its digital signature, because the assemblies can be signed and a private key is stored at software team only. Nevertheless, it's possible to run Client software under debugger and capture the Ku key before decryption of the Authentication Token.

That leads to one obvious solution which I don't really like. The client software should be protected with one of the powerful software protection tools which, in particular, make both code analysis and debugging impossible (I have experience working with XHEO Code Veil, http://xheo.com/products/code-protection). The problem is that powerful solutions are proprietary. The real problem is not even license and royalty costs which can be considerable, but the lack of opportunity to evaluate strength of protection and validity of company's claims. That will solve the problem in principle, but again, it doesn't make me satisfied.

Unfortunately, this is inherent problem of the approach when the modification of Client software is freely distributed and the possibility of the modified Client behavior presents a threat. I already expressed my concern: this can be considered as the bigger architectural problem, a fragility of the general data model. However, I clearly realize that rethinking of this model can be not feasible.

Part 3



The schema with software protection (Part 2) was actually a combination with Part 1, a plan "B". I think the problem needs a radically different approach, plan "C". It should not require global change in the architecture and sit in the thin communication layer between Service and Client.

My idea is moving all business logic from Client part to Service, where it is not accessible for modification. This is relatively small modification of the architecture. There can be different approaches.

One obvious approach is transforming of the application into ASP.NET tier to represent the complete communication layer between Service and Client. This is quite doable. The potential problem is significant change in client capabilities due to limitations of HTTP protocol.

Alternative approach is to stay with regular UI-enabled client working through the transport protocol, but cleared from business logics, which is moved to the Service-part counterpart. Here I have some preliminary schemas which need some extra thinking.

—SA


这篇关于如何确保只有定义良好的客户端与Web服务(WCF)进行通信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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