【问题标题】:Is using X509 for WCF security inherently slow with a new channel per-request?使用 X509 进行 WCF 安全性是否会因每个请求的新通道而固有地变慢?
【发布时间】:2012-03-09 15:06:13
【问题描述】:

我可以做些什么来使 X509 性能更好遵循 new-channel-each-request 最佳实践,或者这种缓慢的协商是否是使用 X509 实现 WCF 安全性的固有缺点?

对于 tl;dr,请跳到末尾的 Update 3 以了解此内容的来源。

WCF 通道的最佳实践似乎是“重用 ChannelFactory,但为每个请求创建一个新通道”,我一直都是这样做的。例如。 Single WCF channel performance vs multiple channels

我目前正在尝试使用 X509 证书作为安全凭证,并且 CreateChannel 每次都需要很长时间(15 秒以上)。重用通道随后会产生良好的性能(如果我理解正确,因为在调用 CreateChannel 时使用了初始公钥/私钥身份验证之后使用了对称密钥),但这是不好的做法。

在服务器端:

var managerCertificate = new X509Certificate2(@"Manager.pfx", "");
var host = new ServiceHost(typeof(ManagerService));
host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
host.Credentials.ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
host.Credentials.ServiceCertificate.Certificate = managerCertificate;
host.Open();
Console.ReadLine();

在工作端(减慢每个请求):

var workerCertificate = new X509Certificate2(@"Worker.pfx", "");
var cfact = new ChannelFactory<IManagerService>("client");
cfact.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
cfact.Credentials.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck;
cfact.Credentials.ClientCertificate.Certificate = workerCertificate;
for (int i = 0; i < 10; i++)
{
    using (IManagerService channel = cfact.CreateChannel()
    {
         Console.WriteLine(channel.GetMyData("test data" + i));
    }
}

如果我将 CreateChannel 调用移到 for 循环之外以重用它,那么只有第一个请求会花费大量时间。

另外,我正在使用 NetTcpBinding。

更新 1:结果的简短示例:

0: 546.875ms
1: 281.25ms
2: 281.25ms
3: 17484.375ms
4: 250ms
5: 234.375ms
6: 250ms
7: 250ms
8: 265.625ms
9: 250ms

每次调用 250 毫秒的开销并不算太可怕(尽管与重用通道相比是巨大的),但似乎会时断时续(参见 17 秒),频率会发生变化,有时是 1 比 3。如果服务器在客户端 exe 运行之间保持正常运行,那么初始协商成本在后续运行中消失,这很好。

更新 2: 可能与防火墙/防病毒无关,因为我在一个 VM 中尝试了这个,并且禁用了股票 XP 和防火墙,结果非常不一致。一次是可预测的(每次调用 400 毫秒),另一次是这些疯狂的停顿。

更新 3: 在浏览跟踪日志后,每次创建新频道时似乎耗时的服务器活动(以及导致偶尔暂停的活动)是这样的:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
  <System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
    <EventID>0</EventID>
    <Type>3</Type>
    <SubType Name="Transfer">0</SubType>
    <Level>255</Level>
    <TimeCreated SystemTime="2012-03-10T15:02:27.2968750Z" />
    <Source Name="System.ServiceModel" />
    <Correlation ActivityID="{9e5e819b-e837-40b8-81b1-9f3c18e54595}" RelatedActivityID="{2faaac57-4e24-41ad-a3e5-85d81bddfa3b}" />
    <Execution ProcessName="WcfCertExample" ProcessID="420" ThreadID="4" />
    <Channel />
    <Computer>MYCOMPUTER</Computer>
  </System>
  <ApplicationData></ApplicationData>
</E2ETraceEvent>

日志还显示:相关活动名称:流程操作“http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue”。

因此,如果有人对为什么这可能会持续暂停 17.5 秒以及它是否总是会正常花费 250 毫秒有任何想法,那么您将回答我的问题!

【问题讨论】:

  • 我也见过stackoverflow.com/questions/1065182/…,但这并不真正适用于netTcpBinding。
  • 基于证书的安全性不会导致此延迟。问题一定出在其他地方,很可能是网络级别的问题或检查证书的有效性。
  • 这些是从文件系统加载的自我证书,并且 CertificateValidationMode 设置为 none,所以我不确定这是否排除了证书有效性检查的原因。我会在一些不同的机器上试试这个。
  • 如果有人在更新 3 之后有想法并需要更多信息,请尽管询问。
  • 没有答案的相关 MS 问题:social.msdn.microsoft.com/Forums/ar/wcf/thread/…

标签: c# .net wcf x509certificate


【解决方案1】:

根据您使用自签名证书的 cmets。

WCF 和自签名证书存在一个已知的性能问题,请参阅:Terrible Performance with WCF and certificates (mutual authentication)

当您使用来自证书颁发机构的证书时,这不是问题。

【讨论】:

  • 链接中的重要说明。使用 MakeCert 制作的 CA 可以正常工作,您无需设置适当的证书颁发机构即可获得性能优势。
  • 关于您在其他帖子中引用的声称自签名证书存在性能问题的链接:他们根本没有提供任何证据来支持该声明,所以我不确定它是否被视为“已知问题” “除非你有其他信息。无论如何,我尝试了一些“正确”的证书并遇到了同样的问题。
猜你喜欢
  • 2014-07-08
  • 1970-01-01
  • 2011-01-15
  • 2014-03-03
  • 2012-12-07
  • 2013-12-03
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
相关资源
最近更新 更多