WCF NetTcpBinding安全性 - 它是如何工作的?

29

在处理WCF设置的泥潭时,我遇到了以下问题...

我使用NetTcp绑定创建了一个WCF客户端-服务器服务。我没有更改安全设置,当在一台机器上运行时,它非常好用。但是,当我从另一台机器运行客户端时,它抱怨服务器不喜欢发送的安全凭据。

我现在明白NetTCP默认情况下是“安全”的,我的客户端将会传递错误的安全详细信息,即Windows用户名和密码(或某种形式的域身份验证)到我的服务器,由于他们不在同一个域中,因此不会让它喜欢。

但是,我不理解的是:

我没有在绑定中指定任何安全性 - 标准设置是否期望发送Windows用户名或密码?

我没有在服务器上安装任何证书 - 我了解NetTCP绑定需要某种公共私有密钥来保护凭据 - 但是当客户端和服务器都在同一台机器上运行时,这似乎是有效的,数据是如何加密的呢?还是因为WCF知道它在同一台机器上,因此不需要加密?

现在我必须将客户端和服务器上的安全模式设置为“无”,它们可以很好地连接。但是是否有一种方法可以在没有证书的情况下加密我的数据?

最后...传输安全和消息安全之间有什么区别?

为了检查我的理解(原谅场景!),消息安全就像我向B发送信件,我对我的手写进行编码以确保任何人拦截它时都无法阅读?传输安全是如果我决定使用武装运输发送我的信件,以便任何人都不能接近它?

是否可能在没有证书的情况下在WCF中进行任何形式的加密?我的项目是私人项目,我不想购买证书,而且数据也不是那么敏感,所以这只是为了我的知识。

1个回答

33
NetTcpBinding的默认客户端凭据类型是Windows身份验证。为了使Windows身份验证工作,客户端和服务器必须在同一个域中,或者彼此信任的域(在您的情况下,您没有这样的域)。
如果客户端和服务器在同一个域上,WCF将在幕后处理Windows身份验证的机制。当客户端和服务器位于同一台计算机上时,它们实际上处于同一个域中,因此Windows可以使用自己的机制来处理加密和解密。然而,这只会在相互信任的域内执行。
如果您没有相互信任的客户端和服务器域,则客户端和服务器必须有其他方法来确定它们是否相互信任其密钥。这就是证书发挥作用的地方。客户端和服务器都有自己的证书(或服务器可以向客户端颁发证书)。
传输安全就像同时保护信封内外的加密方式。缺点是,如果您必须将信封传递给组织以外的人,他们需要一个解密密钥才能知道信封应该去哪里,现在他们还可以读取信封中的消息。另一方面,传输安全更快-它需要通过传递与信封相关的较少的安全开销数据。
消息安全加密您的消息,但是邮政工人(互联网及其路由器)可以读取信封。只有源和目的地拥有解密消息的密钥,但中间人可以正确路由您的消息。
总之,要在NetTcpBinding上使用加密,客户端和服务器必须在域内(或相互信任的域内),否则您必须拥有密钥交换证书。
编辑:有人要求一些示例代码-这是XAML中的绑定元素。它通常会放置在netTcpBinding元素内部。
<binding name="Secure" listenBacklog="4000" receiveTimeout="00:20:00" sendTimeout="00:20:01" 
   maxReceivedMessageSize="2147483647" maxConnections="200" portSharingEnabled="true">
   <!-- ~2 GB -->
   <readerQuotas maxStringContentLength="2147483647"/>
   <!-- ~2 GB max string content length -->
   <security mode="Message">
      <transport clientCredentialType="None" protectionLevel="EncryptAndSign"/>
      <message clientCredentialType="None"/>
   </security>
</binding>

重要的部分是安全元素。对于传输安全,应将 mode 属性更改为 "Transport"。很可能 clientCredentialType 不是 "None",而是根据上下文选择 "Certificate"、"Ntlm" 或 "Windows"。


我知道这是一篇旧帖子 - 但传输安全配置和消息安全配置的示例代码会很有帮助。我的知识在这里缺乏...我以为我可以在没有证书的情况下使用NetTcpBinding上的UserName,只需选择TransportWithMessageCredential即可 - 但由于某种原因,我正在阅读他们没有告诉你的东西,即除非你至少拥有服务器证书,否则不存在用户名密码验证。这是真的吗? - Stix
1
你需要一张证书,或者服务器和客户端需要在相互信任的域中(通常这意味着它们必须在同一个域中,除非你准备进行一些复杂的操作)。 - Matt Smith
如果你设置了<security mode="None">,那么你发送的是明文吗?还是默认加密了?感谢您的帖子。 - RayLoveless
安全模式“无”会以明文发送数据,除非其他设备(例如IPSec硬件)对数据进行加密。 - Matt Smith
我不确定这个回答有多准确。例如,您可以为绑定定义传输安全模式,这意味着SSL。该示例使用消息模式安全,但定义了<transport>元素,这是多余的,我认为。 - Kyberias

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接