使用 x509 加密的 WCF Net.TCP 非常慢

标签 wcf performance wcf-security digital-certificate

我正在使用 WCF 开发客户端-服务器应用程序。 WCF 服务使用数字证书进行保护。我正在使用消息安全性,因为我要求客户端在对服务器的任何调用中提供成员(member)用户名/密码。服务器由 Windows 服务托管。我在生产服务器上安装了证书服务并使用它来创建服务器身份验证数字证书。

服务器的数字证书使用sha1作为哈希算法,公钥为1024位。

客户端 WCF 代理由 Visual Studio 生成(通过添加服务引用)。在我的客户端中,我使用 WCF 代理的单例实例。

问题是,当 WCF 的安全模式设置为“消息” 或 < em>“TransportWithMessage”。

当服务器和客户端位于同一台计算机上时,应用程序在我的本地计算机和生产服务器上运行得非常快。这排除了与 SQL 查询相关的任何性能问题。

比较有安全性和没有安全性的性能。我使用了以下操作:

操作:

  1. 检查登录凭据:调用的测试函数,如果返回安全异常,则凭据不正确。
  2. 获取列表:返回 11 个 (EF DbContext) 实体列表的函数。
  3. 按 ID 获取记录:返回加载了一些“单一多重性”导航属性的单个实体。

我使用 WireShark 记录对这些操作的服务调用的持续时间和数据大小。我对带安全性的 wsHttpBinding、带安全性的 netTcpBinding 和不带安全性的 netTcpBinding 重复了测试,结果如下:

Results table

当客户端和服务器在同一台机器上时,任何操作的持续时间始终小于一秒。

这是 WCF 服务器的配置文件:您会注意到我有两个绑定(bind)和两种行为,一种用于安全通信,另一种用于不安全通信。

<?xml version="1.0"?>
<configuration>
    <connectionStrings>
        <add name="HS" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=HS;Integrated Security=True" providerName="System.Data.SqlClient"/>
        <add name="HSContext" connectionString="metadata=res://HS.Model/Model.csdl|res://HS.Model/Model.ssdl|res://HS.Model/Model.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=.\SQLEXPRESS;initial catalog=HS;integrated security=True;multipleactiveresultsets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
    </connectionStrings>
    <system.web>
        <compilation debug="true" targetFramework="4.2"/>
        <authentication mode="Forms">
            <forms name=".HSYAUTH" loginUrl="~/Account/LogOn" cookieless="UseCookies" protection="All" slidingExpiration="true" timeout="2880"/>
        </authentication>
        <machineKey validationKey="..." decryptionKey="..." validation="HMACSHA256" decryption="AES"/>
        <membership defaultProvider="SqlMembershipProvider" userIsOnlineTimeWindow="15" hashAlgorithmType="SHA256">
            <providers>
                <clear/>
                <add applicationName="HS" name="SqlMembershipProvider" connectionStringName="HS" passwordFormat="Hashed" minRequiredNonalphanumericCharacters="0" minRequiredPasswordLength="6" maxInvalidPasswordAttempts="5" enablePasswordReset="true" enablePasswordRetrieval="false" passwordAttemptWindow="10" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" type="System.Web.Security.SqlMembershipProvider"/>
            </providers>
        </membership>
        <profile>
            <providers>
                <clear/>
                <add name="SqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="HS" applicationName="HS"/>
            </providers>
            <properties>
                <add name="WebSettingsTestText" type="string" readOnly="false" defaultValue="DefaultText" serializeAs="String" allowAnonymous="false"/>
            </properties>
        </profile>
        <roleManager enabled="true" defaultProvider="SqlRoleProvider">
            <providers>
                <clear/>
                <add connectionStringName="HS" applicationName="HS" name="SqlRoleProvider" type="System.Web.Security.SqlRoleProvider"/>
                <add applicationName="HS" name="WindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider"/>
            </providers>
        </roleManager>
    </system.web>
    <system.serviceModel>
        <services>
            <service name="HS.Services.HS" behaviorConfiguration="SecureServiceBehavior">
                <host>
                    <baseAddresses>
                        <add baseAddress="net.tcp://0:808/Services/HS.svc"/>
                    </baseAddresses>
                </host>
                <endpoint address="" binding="netTcpBinding" contract="HS.Services.IHS" bindingConfiguration="SecureBinding">
                    <identity>
                        <dns value="{my server ip address}"/>
                    </identity>
                </endpoint>
                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
            </service>
        </services>
        <behaviors>
            <serviceBehaviors>
                <behavior name="SecureServiceBehavior">
                    <serviceMetadata/>
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                    <serviceCredentials>
                        <serviceCertificate findValue="CN={my server ip address}" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectDistinguishedName"/>
                        <clientCertificate>
                            <authentication revocationMode="NoCheck"/>
                        </clientCertificate>
                        <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="SqlMembershipProvider"/>
                    </serviceCredentials>
                    <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="SqlRoleProvider"/>
                    <serviceThrottling maxConcurrentCalls="128" maxConcurrentSessions="128" maxConcurrentInstances="128"/>
                </behavior>
                <behavior name="InsecureServiceBehavior">
                    <serviceMetadata/>
                    <serviceDebug includeExceptionDetailInFaults="true"/>
                    <serviceCredentials>
                        <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="SqlMembershipProvider"/>
                    </serviceCredentials>
                    <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="SqlRoleProvider"/>
                    <serviceThrottling maxConcurrentCalls="128" maxConcurrentSessions="128" maxConcurrentInstances="128"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <bindings>
            <netTcpBinding>
                <binding name="SecureBinding" receiveTimeout="00:10:00" sendTimeout="00:10:00" closeTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="20000000" portSharingEnabled="false">
                    <security mode="Message">
                        <message clientCredentialType="UserName"/>
                    </security>
                    <readerQuotas maxDepth="32" maxArrayLength="200000000" maxStringContentLength="200000000"/>
                </binding>
                <binding name="NoSecureBinding" receiveTimeout="00:10:00" sendTimeout="00:10:00" closeTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="20000000" portSharingEnabled="true">
                    <security mode="None">
                    </security>
                    <readerQuotas maxDepth="32" maxArrayLength="200000000" maxStringContentLength="200000000"/>
                </binding>
            </netTcpBinding>
        </bindings>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
    </system.serviceModel>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
    </startup>
</configuration>

这是WCF客户端的配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_IHS" receiveTimeout="00:10:00" sendTimeout="00:10:00" closeTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="20000000" portSharingEnabled="false">
                    <security mode="Message">
                        <message clientCredentialType="UserName" />
                    </security>
                </binding>
                <binding name="NetTcpBinding_IHS_Insecure" receiveTimeout="00:10:00" sendTimeout="00:10:00" closeTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="20000000">
                    <security mode="None">
                    </security>
                </binding>
            </netTcpBinding>
        </bindings>
        <client>
            <endpoint address="net.tcp://{my server ip address}:808/Services/HS.svc" binding="netTcpBinding"
                bindingConfiguration="NetTcpBinding_IHS" contract="ServiceReference.IHS"
                name="NetTcpBinding_IHS">
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

一周以来我一直在努力解决这个问题,但没有任何明显的进展。具有安全性的 WCF 速度慢吗?或者我做错了什么?

最佳答案

如果您担心速度,请考虑仅使用传输安全。消息正文加密将比保护整个 channel 慢得多。

关于使用 x509 加密的 WCF Net.TCP 非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11460251/

相关文章:

c++ - 本地对象的性能改进

.net - 是什么导致 WCF 服务/服务器期望 'Negotiate,NTLM' ?

.net - 将wsHttpBinding SSL传输安全性与消息安全性结合使用有什么好处?

java - 插入排序比 shell 排序快得多

c# - 使用传输模式证书保护 WCF

asp.net-mvc - 发送电子邮件到哪里去?服务层还是 Web 层?

c# - 在 WCF 中使用 Unity 将依赖项注入(inject)属性

wcf - Visual Studio 2015 + Xamarin + native 可移植 PCL + WCF

wcf 绑定(bind)配置和安全性

c++ - 在 C++ 中复制列信息