对于 WCF 服务,没有证书的 TransportWithMessageCredential 是不是足够安全?

Posted

技术标签:

【中文标题】对于 WCF 服务,没有证书的 TransportWithMessageCredential 是不是足够安全?【英文标题】:Is TransportWithMessageCredential without certificate secure enough for a WCF service?对于 WCF 服务,没有证书的 TransportWithMessageCredential 是否足够安全? 【发布时间】:2012-05-28 14:32:33 【问题描述】:

我开发了一个 WCF 自托管服务,我有两个基本的安全要求,因为它将通过 Internet 访问:

传输层应防止篡改和嗅探,尤其是检索身份验证凭据。这就是 SSL 所做的,但据我所见,设置 SSL 需要安装证书(可能通过使用普通证书文件的 this hack 除外),我不想这样做。

身份验证层应包含用户名/密码验证器。

我将我的服务配置为使用:

      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="UserName" />
        <transport clientCredentialType="Basic" />
      </security>

即使传输层是 HTTP(不是 HTTPS),这是否会让 WCF 创建另一个等同于 SSL 的安全层?如果不是,在安全强度方面有什么区别?

另外,有没有什么方法可以在不使用 SSL 证书的情况下保护元数据端点(不是必需的,但不胜感激)?

这是我的自托管服务的完整配置代码:

<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
  <system.serviceModel>
    <services>
      <service name="MyService">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8000/Services" />
          </baseAddresses>
        </host>
        <endpoint address ="MyService" binding="wsHttpBinding" contract="IMyService">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="Binding1" maxReceivedMessageSize="2147483647">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName" />
            <transport clientCredentialType="Basic" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CR.Common.Services.CustomValidator, Common" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

谢谢!

【问题讨论】:

【参考方案1】:

默认情况下,所有安全 WCF 绑定(如 wsHttpBinding)都会对消息进行加密和签名。

SSL 强制使用证书,并且您提供的链接中的 hack 是 hacking wcf,而不是 SSL。因为没有 SSL WCF 禁止使用 basicHttpBinding(以明文形式发送 xml)和 UserNamePasswordValidator,因为在这种情况下,任何拦截消息的人都可以获得用户名/密码。

使用 WSHttpBinding,您可以避免 SSL 并将安全性置于消息级别。

我强烈建议您阅读this article,尤其是服务凭证和协商一章:

为了支持相互身份验证和消息保护,服务必须 向调用者提供凭据。使用传输安全性时 (SSL),服务凭证通过传输协商 协议。消息安全的服务凭证也可以是 使用 Windows 凭据时协商;否则服务 必须指定证书

使用UserNamePasswordValidator,您必须在服务器上配置证书以允许客户端签名并加密每条消息(使用证书的公钥)。 如果您使用的是 Windows 身份验证,则不需要。

你为什么这么担心证书?

【讨论】:

如果可能的话,我只想要一个没有证书的简单安装。服务器需要自定义用户名/密码(无 Windows 身份验证)然后保证通信机密性和完整性的东西。 正如我告诉你的,你需要“一些东西”来签署和加密消息,这就是你 UserNamePasswordValidator 需要证书的原因。您可以找到一些 hack 使其无需证书即可工作,但是您的消息将不会被签名/加密。安装证书非常简单,您也可以使用自动签名的证书(在服务器本身上生成),这样就不会花费您一些钱。 我最终只使用了服务器证书,尽管我仍然相信对于像我这样的场景来说它可以变得更简单。

以上是关于对于 WCF 服务,没有证书的 TransportWithMessageCredential 是不是足够安全?的主要内容,如果未能解决你的问题,请参考以下文章

WCF自寄宿实现Https绑定

没有身份验证的 WCF 传输安全性

没有证书的 WCF 用户名

WCF 服务配置异常“证书可能没有私钥......”

WCF 错误:“证书“我的证书”可能没有能够进行密钥交换的私钥

WCF客户端 - EncryptedKey子句未包含所需的加密令牌