【问题标题】:WCF message security without certificate and windows auth没有证书和 Windows 身份验证的 WCF 消息安全性
【发布时间】:2010-12-06 22:56:37
【问题描述】:

我有一个 WCF 服务和客户端,将部署到几家公司(数百家)。有些公司会在他们的网络中运行软件,有些公司会通过 Internet 运行(WCF 服务器在办公室,WCF 客户端在另一个)。

我们想要加密 WCF 服务器和客户端之间的通信。我们不需要使用 WCF 安全性对 cient / 订阅者进行身份验证,因为我们有自己的用户名/密码登录,客户端将使用它登录服务器。

  • 我们不能依赖 Windows 身份验证,因为一些用户将通过 Internet 运行它,而且 WCF 服务器可能与 WCF 客户端不在同一个域中。
  • 如果我们使用“真实”证书*,运行该软件的公司将不得不从 CA 购买证书并安装它,然后配置我们的软件以使用它,但这对于大多数公司来说太复杂了。
  • 我们可以在安装 WCF 服务器的过程中自动创建证书,但是我们必须自动将其安装到证书存储中,并以某种方式自动授予 IIS 读取证书的权限。这比我们想象的要复杂。

简而言之,我们想要一个简单的解决方案,其中加密仅基于共享机密,在我们的例子中是用户登录时使用的用户名/密码。我明白这不会提供最好的可用加密,但我们愿意牺牲一些安全性以使软件更易于部署。

这可能吗?

*“真实”证书是指从证书颁发机构购买的证书,而不是我自己创建/自签名的证书。

【问题讨论】:

  • 您的第三个场景(脚本安装)非常好。为什么你认为它很复杂?安全性本质上是一个复杂的方面。使用 msbuild 或 powershell 通过良好的安装文档来实现您的目标。
  • > 为什么你认为它很复杂?安全性本质上是一个复杂的方面。那你在说什么?复杂不复杂? :) 另外,MSBuild 是如何出现在这里的?在我们的软件编译过程中,我们无法真正自动生成 SSL 证书。自动生成的证书必须对每个客户都是唯一的。

标签: wcf encryption certificate message


【解决方案1】:

如果您想加密传输中的消息(这真是个好主意!),发送者(客户端)和服务器之间必须有一些共享知识。这可以是硬编码的,但这根本不是一个好主意 - 如果“公共共享”知识遭到破坏,攻击者可以破译并阅读您的所有消息。

此外,由于这绝对是推荐的做法,因此 WCF 中不支持任何类型的简化共享密钥的使用。你是靠自己的——你必须100%自己动手。

唯一可行的方法是使用证书以安全的方式交换公共共享秘密。没办法,抱歉。证书甚至不必用于用户身份验证或其他任何事情 - 但它在调用者和服务之间建立了一个共享秘密,因此允许调用者以只有预期接收者才能实际解密和使用的方式加密消息他们。

所以我真的看不出有什么办法可以绕过在服务器上安装证书 - 不需要在每个客户端上,而是在运行服务的每台服务器上。

马克

PS:如果你真的想研究“硬编码共享密钥”的方法,你需要考虑这个:

  • 您如何在您的每一个客户端上安全地存储共享密钥?
  • 您如何使用存储的共享密钥中的信息来加密您的消息?

通常,该方法有两种:

  1. 交换某种形式的私钥/公钥对;服务器生成一个密钥对并将私钥保存给自己,并与客户端共享公钥(例如,通过 WCF 消息)
  2. 使用该私钥/公钥对,交换一个共同的共享秘密,例如对称加密消息的“加密密钥”(由于它是对称的,服务器可以使用相同的密钥来解密消息)
  3. 在您的客户端上设置基础架构(例如,称为行为的 WCF 扩展)以在消息发出之前检查消息并使用您的共享密钥对其进行加密

总而言之,这真的很重要——任何比这更简单的东西都不值得被称为“安全性”。

如果您看看您必须做的所有工作 - 使用 WCF 内置证书机制不是更容易吗??

物有所值的安全很难 - 所以为什么不利用可用的东西而不是自己做所有的工作,或者更糟:想出一个很容易破解的半生不熟的解决方案,你可以就像以明文形式轻松发送所有内容一样......不要低估处理最基本的安全场景所需的代码的复杂性和数量 - WCF 为您完成这一切 - 免费且以可靠和安全的方式 -用它!你不会后悔的!

【讨论】:

  • 正如我在问题中所写,我已经知道我可以使用证书这一事实。我的问题是是否有基于简单用户名和密码身份验证而不是证书的替代方法。我没有看到你已经回答了这个问题。
  • 我做到了 - 我说过 IS 没有别的办法。要么你有证书来为你的消息提供安全和加密,要么你必须放弃加密。任君挑选。
  • 如果你想要加密(并且你!),那么你需要一个共享的秘密——要么是硬编码(不推荐)到你的客户端配置中的,要么然后当前可用的另一个选项是证书。
  • 你最后的两个 cmet 似乎相互矛盾。首先,您写道唯一的选择是使用证书。然后您写道,我可以使用共享的硬编码机密或证书。我认为后一种是正确的。那么我该如何使用共享的、硬编码的、秘密的呢?
【解决方案2】:

嗯,使用 WCF,您可以在消息级别使用密码凭据,在传输级别使用 SSL,我认为这对您来说就足够了。

here

【讨论】:

  • 传输级别的 SSL 不需要安装证书吗?在那种情况下,它真的不符合我列出的要求吗?您链接到的页面显示密码凭据在消息级别不可用;只是用户名。密码用于传输凭证。此外,在“消息客户端凭据类型”下,您所指的页面显示“请注意,WCF 不允许使用用户名进行任何加密操作,例如生成签名或加密数据。”。你能解释一下你的意思吗?
  • 对于证书,正如 marc_s 所说,可能没有办法绕过这些。对于密码的东西,你是绝对正确的,我的错 :) 也许你可以尝试在将数据放入消息之前手动加密数据,或者使用消息检查器这样做?但是,我认为您在使用自己的安全机制之前应该三思而后行。
  • > 也许您可以尝试手动加密数据,然后再将它们放入消息中。这个想法已经闪过我的脑海,但我放弃了它。我无法编写自己的安全机制,即使可以,我也必须在消息仍被序列化时截获该消息,这将是一件痛苦的事情。 > 对于证书,正如 marc_s 所说,可能没有办法绕过这些。我在 StackOverflow 上寻找的东西是确定性的,而不是更“可能”的东西。我花了几个小时在谷歌上搜索这个主题,但似乎没有人确切知道。
  • 如果你在客户端和服务器上都设置了一个检查器来拦截消息并在它发布到客户端/服务器之前修改它的内容,你可以很容易地使用你自己的加密机制。这不会反映在接触中,但我能看到什么并不重要。或者您有什么不能使用消息检查器的原因?
  • 嗨,关于如何在客户端和服务器上放置检查器以拦截消息并在将其发布到客户端/服务器之前修改其内容,是否存在任何好的文章
【解决方案3】:

为了消息安全,您的客户端提供一些凭据,而服务器提供一些凭据。对于此设置和您的方案,您是否可以不使用带有Custom Username Validator 的客户端用户名和密码以及服务器证书来提供服务器凭据。这个Application Scenario 提供了实现这一点所需的配置设置的一个公平的部分,除了 aspNet 成员部分,您必须用您的自定义验证配置替换它。

您仍然需要服务器上的有效证书(客户端不需要证书),但我看不出有任何解决方法。

【讨论】:

    【解决方案4】:

    看看下面的例子:

    http://www.codeproject.com/KB/WCF/wcfcertificates.aspx

    它使用证书但没有证书存储 - 所以不需要设置。

    【讨论】:

      【解决方案5】:

      嗯..也许可以使用一些简单的东西。将加密从软件转移到硬件。从每个客户端网络到您自己的 VPN,然后您可以为 WCF 传输做任何您喜欢的事情。该行不是明文,问题解决了。

      当然,这说起来容易做起来难,但大多数网络供应商都提供了一个非常简单的 VPN 配置,而且它可能比尝试为 SSL 证书开发安装程序和配置客户端更容易。

      希望对你有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-08
        • 2014-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-16
        • 1970-01-01
        相关资源
        最近更新 更多