WCF服务证书和客户端端点身份验证 - 为什么不起作用?

10
[更新] - 我还附上了完整的配置文件,用于服务端客户端(不在这里发布,以免淹没主题)。
我遇到的情况与此问题中描述的情况几乎相同,但我的问题略有不同。
  • 我正在使用安全性设置为TransportWithMessageCredential的NetTcpBinding。
  • 我正在使用由ASP.NET提供程序支持的密码/用户名凭据。
  • 我的服务是托管在Windows Service中的自托管应用程序程序。
  • 我在我的终结点行为中指定了身份验证revocationMode ="NoCheck"。
需要该服务提供证书来对客户端进行身份验证。没问题,我只需:
<serviceCertificate findValue="***"
                    storeLocation="CurrentUser"
                    storeName="My"
                    x509FindType="FindByThumbprint"/>

现在,我有点想象客户最终会拥有

<identity>
  <certificate encodedValue="encoded certificate"/>
</identity>

它将能够验证服务的凭据,而无需在客户机上安装该证书

我很惊讶地发现,尽管我将服务凭据设置为证书,但WSDL仍然公开了

<Identity>
   <Dns>Foo</Dns>
</Identity>

在服务中,我可以将Identity设置为CertificateReference,并将其连接到同一证书,然后WSDL将把身份公开为X509Certificate,但是当我运行客户端时,该设置被忽略,我最终会遇到错误消息:

System.ServiceModel.Security.SecurityNegotiationException: X.509证书CN=xxx不在受信任的人员存储中。X.509 证书CN=xxx链构建失败。使用的证书具有无法 验证的信任链。替换证书或更改certificateValidationMode。 证书链已经被处理,但是以根证书结束,而这个根证书不被信任提供商所信任。

是否有一种方法可以使客户端使用配置文件中的值并且无需在客户机上安装服务证书(也不需要安装其根证书)而正常工作?

[更新] 将certificateValidationMode设置为none可以消除异常,但从安全角度来看,这是不可接受的解决方案。

它只是让客户端承认“某个”证书而没有进一步细节。这使得所有的中间人攻击都成为可能。它仍然不会验证在配置文件中转储的证书针对(被指控的)服务发送的信息。

5个回答

4
解决方案简述:
1)为客户端定义并注册一个自定义的X509CertificateValidator。
2)在Validate方法中,将给定的证书与客户端EndpointAddress.Identity属性中存在的证书进行比较。该属性引用的对象应具有X509CertificateEndpointIdentity确切类型。
我没有测试过这个解决方案,但对我来说很有道理。
希望有所帮助 Pedro

这是我最终做的。但我有一个问题——为什么它不能直接工作?如果客户端拥有所有必要的信息,并从服务中接收一些证书,将其与其他证书进行验证是最自然的事情。为什么WCF不这样做呢? - Krzysztof Kozmic
猜测:出于安全原因。使用所提出的解决方案,WSDL导入过程的安全性变得更加关键,因为在与服务通信时不会执行任何额外的证书验证。 - Pedro Felix
我刚刚在我的问题上设置了一个赏金,这个问题似乎与你在这里说的类似。如果你能在那里更详细地解决这个问题,我会非常感激!http://stackoverflow.com/questions/4579666/wcf-newbie-how-to-install-and-use-a-ssl-certificate - Shaul Behr

2
[更新] 将certificateValidationMode设置为none可以使异常消失,但从安全角度来看,这是不可接受的解决方案。它只是让客户端承认收到了“某些”证书,而没有进一步细节信息。这使得中间人攻击成为可能。它仍然无法验证(所谓的)服务发送的信息与配置中的证书是否匹配。
你错了。这样做完全没问题。实际上这正是你想要的——你的证书不被验证。你只需要将客户端端点的标识设置为:
<identity>
  <certificate encodedValue="encoded certificate"/>
</identity>

当客户端连接到服务器时,WCF将比较两个证书,如果不匹配,则会抛出异常。您是完全安全的。
在您的情况下,像Pedro Felix建议的使用自定义验证器是完全不必要的。这正是终结点身份的作用。

这是误导性的 - 将certificateValidationMode设置为None意味着您可以拥有任何encodedValue,而不会被检查。 - James Crowley

2
抱歉,我不能对其他答案发表评论。
我刚在.NET 4.0中进行了测试,并确认"Zeratul"的答案是正确的。在配置文件或编程方式中明确设置服务的标识已足够进行服务器身份验证。没有必要通过任何其他方式验证证书(即您可以将“certificateValidationMode”设置为“None”),因为您正在使用最终的验证方法-比较证书的指纹。
“serviceCertificate”不用于验证。它与消息安全一起使用,以加密发送到服务器之前的消息。请参阅Microsoft的文档。

http://msdn.microsoft.com/en-us/library/ms731782.aspx


1

这是我之前回答的附加评论。很抱歉我不能评论答案。

此外,您不需要在服务器上设置任何身份。忘记WSDL告诉您有关服务器身份的内容。远程服务端点的身份由客户端在运行时决定。如果服务器使用SSL,则它具有多个身份:证书的通用名称(即DNS身份),证书身份和RSA身份(对于最后一个我不确定)。因此,您可以通过这些标准之一(或几个标准)检查服务器的身份。


0

你做得很好,几乎完成了客户端配置。但是你还缺少最后一步(如错误描述中所述):需要在配置中将revocationMode设置为NoCheck:

 <behaviors>
  <endpointBehaviors>
    <behavior name="SecureMessageUserName">
      <clientCredentials>
         <serviceCertificate>
            <authentication revocationMode="NoCheck"/>
         </serviceCertificate>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
 </behaviors>

如果您需要更多细节,请告诉我,我会发布完整的客户端配置。 编辑 抱歉耽搁了。
您还应该在服务器配置中添加noCheck:
<behavior name="X509SecureBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <serviceCertificate storeName="My" storeLocation="CurrentUser" x509FindType="FindByThumbprint" findValue="aaaa" />
            <clientCertificate>
              <authentication certificateValidationMode="None" revocationMode="NoCheck" />
            </clientCertificate>
          </serviceCredentials>
        </behavior>

另外,我也没有在端点定义中包含证书引用。


抱歉,我忘记提到我已经设置了这个选项。我已经相应地更新了问题。无论我在这里指定什么,证书似乎都被忽略了。 - Krzysztof Kozmic
你能发布完整的配置文件吗?或者其中重要的部分? - AlexDrenea
当然可以,我链接了它们,因为它们非常大,我不想让潜在有帮助的人被淹没在大量的XML中而感到害怕。 - Krzysztof Kozmic
我不是在抱怨,但这个解决方案对我来说并不可行 :( - Krzysztof Kozmic
我不确定我理解你的意思?它无法工作还是你无法出于其他原因编辑服务器配置? - AlexDrenea
看一下我更新后的问题(在底部)。基本上它确实消除了异常,并调用了succeed,但它并没有让客户端使用在配置中序列化的证书 - 它只是接受任何证书,这是不可接受的 :/ - Krzysztof Kozmic

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