3

My scenario: I have a public facing web app hosted on Amazon EC2 servers. I have a self-hosted database server behind a firewall. I have self-hosted Web Service servers with a web service for data access. I want to allow only applications I approve (my own living in the cloud) to access the services and I don't want any data passed in clear-text.

From what I can tell reading all the disjointed and maddeningly obfuscated MSDN articles, Stackoverflow threads, Code Project articles, and other blogs. The type of security I need is: Transport Security mode with Certificate clientCredentialType, using wsHttpBinding. First question, am I right in assuming that? Will that give me enough security? This isn't B2B or anything like that. It is, however, cross domain and I just want to ensure I can trust the caller. My service is running in an AppPool owned by a specific user so I can access the DB with integrated security. I need to make sure only callers to my service that I approve get in. I don't need to encrypt the message anymore than SSL already does I don't believe.

All the scenarios possible make it very very difficult to know if this is what I want. But assuming it is the next question is how do I set up the Certs? I currently have a Certificate on the server, and I can only access with Https. (security mode="Transport", clientCredentialType="None"). But for the life of me I can't figure out what I need to do to change clientCredentialType to Certificate and get it to work.

  • What do I give the client from the server and where does it go?
  • What do I give the server from the client and where does it go?
  • If I have several clients (a web farm) do I have to have a different client cert for all of them, or can they share one cert that my server accepts?

All development articles I read say that Cert setup is an Admin tool and beyond the scope of the article. Well, the WCF stuff is straightforward, it's exactly the friggin cert stuff I need help with, and there are no useful articles that I've found yet. Those that come close show how to do it with makecert.exe and say in production it will be different, but then don't say how to do it in production.

I'm sure my frustration level is showing, sorry about that. But it really makes no sense that there isn't a clear description on how to do what seems like a pretty common security scenario in WCF.

Any and all help appreciated, Ken

4

1 回答 1

3

简答

我需要的安全类型是:带有证书clientCredentialType的传输安全模式,使用wsHttpBinding。第一个问题,我的假设是否正确?

是的。假设您不使用 WCF 流功能,消息安全性也可以工作,但通过传输安全性,您可以受益于硬件加速。

如何设置证书?

请参阅下面的详细答案。

我从服务器给客户端什么,它去哪里了?如果我有多个客户端(一个网络场),我是否必须为所有客户端提供不同的客户端证书,或者他们可以共享一个我的服务器接受的证书?

您需要 3 个证书:

  • 客户端证书(所有客户端都相同)。
  • 服务器证书。
  • 证书颁发机构 (CA) 证书,由该证书颁发客户端和服务器证书。

客户需要:

  • 安装在个人证书存储中的客户端证书。
  • 安装在受信任的根证书颁发机构存储中的 CA 证书。

我从客户端给服务器什么,它去哪里了?

服务器需要:

  • 安装在个人证书存储中的服务器证书。
  • 安装在受信任的根证书颁发机构存储中的 CA 证书。
  • 安装在受信任的人存储中的客户端证书。

详细解答

在这种情况下(网络场和自托管网络服务之间的通信),您同时拥有客户端和服务器计算机。不需要第三方颁发的证书(您相信自己,对吗?)。这意味着您可以安全地使用自制证书。

这是一个快速指南,希望能帮助您(或其他人)实现这一目标。如果您已经拥有问题所建议的证书,请随时跳过步骤 I。此外,您可能已经购买了第三方颁发的证书,在这种情况下,根证书颁发机构(VeriSign、Microsoft 等)证书可能已经安装在您的客户端和服务器机器。

一、创建证书

如这篇msdn 文章中所述,用于makecert生成 3 个证书:

  1. 一个根证书颁发机构证书,我们称之为它MyRootCA,以及它的撤销列表。
  2. 服务器 SSL 证书。该名称必须是您的 Web 场客户端将用于调用 Web 服务的域名。例如,如果您的客户使用以下 url: https://mywebserver.myprivatedomain.com/service1.svc,那么您的证书 CN(通用名称)将为mywebserver.myprivatedomain.com.
  3. 客户端 X.509 证书,我们称之为MyAmazonClient.

这是一个实现这 3 个步骤的简单批处理:

REM 1: MyRootCA
makecert -n "CN=MyRootCA" -r -sv "MyRootCA.pvk" "MyRootCA.cer"
makecert -crl -n "CN=MyRootCA" -r -sv "MyRootCA.pvk" "MyRootCA.crl"

REM 2: mywebserver.myprivatedomain.com
makecert -sk "mywebserver.myprivatedomain.com" -iv "MyRootCA.pvk" -n "CN=mywebserver.myprivatedomain.com" -ic "MyRootCA.cer" -sr LocalMachine -ss My -sky exchange -pe

REM 3: MyAmazonClient
makecert -sk "MyAmazonClient" -iv "MyRootCA.pvk" -n "CN=MyAmazonClient" -ic "MyRootCA.cer" -sr LocalMachine -ss My -sky signature -pe

此批次将在当前文件夹中创建 3 个文件:

  • MyRootCA.cer:包含根 CA 证书的公钥。
  • MyRootCA.crl:包含证书吊销列表。
  • MyRootCA.pvk:包含根 CA 证书的私钥。

其他 2 个证书(客户端和服务器)安装在本地计算机证书存储中。

使用证书 MMC 管理单元,将它们导出到 .pfx 文件中:

  • 找到 LocalMachine > 我的 > 证书。
  • 右键单击MyAmazonClient > 所有任务 > 导出。
  • 右键单击mywebserver.myprivatedomain.com > 所有任务 > 导出。

二、安装服务器证书

在您的服务器机器(公开 Web 服务的机器)上,复制以下文件:

  • MyRootCA.cer
  • MyRootCA.crl
  • MyAmazonClient.pfx
  • mywebserver.myprivatedomain.com.pfx

使用服务器机器上的证书 MMC 管理单元,在以下位置安装证书:

  • MyRootCA.cerMyRootCA.crlLocal Computer > Trusted Root Certification Authorities > Certificates
  • MyAmazonClient.pfx进入Local Computer > Trusted People > Certificates
  • mywebserver.myprivatedomain.com.pfxLocal Computer > Personal > Certificates

授予 IIS AppPool 对 mywebserver.myprivatedomain.com 证书的私钥的访问权限。在 MMC 证书管理单元中,右键单击 mywebserver.myprivatedomain.com > 所有任务 > 管理私钥...然后添加运行 AppPool 的身份。请注意,使用 ApplicationPoolIdentity(默认情况下)时,身份名称为IIS AppPool\YourAppPoolNameHere.

三、配置 IIS 以支持 SSL

使用 IIS 管理器,找到您的网站并使用您的mywebserver.myprivatedomain.com证书添加 https 绑定。请参阅步骤 4:在 IIS 中配置您的临时服务证书以支持 SSL

四。配置服务 (web.config)

  <system.serviceModel>
    <protocolMapping>
      <add scheme="https" binding="wsHttpBinding" />
    </protocolMapping>
    <bindings>
      <wsHttpBinding>
        <!-- configure wsHttp binding with Transport security mode and clientCredentialType as Certificate -->
        <binding>
          <security mode="Transport">
            <transport clientCredentialType="Certificate"/>            
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
  </system.serviceModel>

五、安装客户端证书

在每台客户端计算机(网络场)上,复制以下文件:

  • MyRootCA.cer
  • MyRootCA.crl
  • MyAmazonClient.pfx

使用客户端计算机上的证书 MMC 管理单元,将证书安装在以下位置:

  • MyRootCA.cerMyRootCA.crlLocal Computer > Trusted Root Certification Authorities > Certificates
  • MyAmazonClient.pfx进入Local Computer > Personal > Certificates

授予您的 IIS AppPool 对 MyAmazonClient 证书的私钥的访问权限(与II相同的步骤)。

六、配置客户端 (web.config)

  <system.serviceModel>
    <client>
      <!-- this endpoint has an https: address -->
      <endpoint address="https://mywebserver.myprivatedomain.com/service1.svc" 
                behaviorConfiguration="endpointCredentialBehavior"
                binding="wsHttpBinding" 
                bindingConfiguration="Binding1" 
                contract="MyWebApp.IServiceContract"/>
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior name="endpointCredentialBehavior">
          <clientCredentials>
            <clientCertificate findValue="MyAmazonClient"
                               storeLocation="LocalMachine"
                               storeName="My"
                               x509FindType="FindBySubjectName" />
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <!-- configure wsHttpbinding with Transport security mode
                   and clientCredentialType as Certificate -->
        <binding name="Binding1">
          <security mode="Transport">
            <transport clientCredentialType="Certificate"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
  </system.serviceModel>

就是这样。

于 2014-07-24T16:34:14.607 回答