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

时间:2012-07-12 20:37:59

标签: wcf performance wcf-security digital-certificate

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

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

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

问题是当WCF的安全模式设置为“Message”或<时,我的生产服务器(专用云服务器和我的本地计算机充当客户端)的应用程序性能很糟糕EM> “TransportWithMessage”

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

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

操作:

  1. 检查登录凭据:调用的测试函数,如果返回安全性异常,则凭据不正确。
  2. 获取列表:一个返回11个(EF DbContext)实体列表的函数。
  3. 按ID获取记录:返回单个实体,其中加载了一些“单重性”导航属性。
  4. 我使用WireShark记录这些操作的服务调用的数据持续时间和大小。我已经重复了对安全性的wsHttpBinding,带安全性的netTcpBinding和没有安全性的netTcpBinding的测试,结果如下:

    Results table

    客户端和服务器在同一台计算机上的任何操作的持续时间总是不到一秒。

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

    <?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的安全性是否缓慢?或者我有什么不对吗?

1 个答案:

答案 0 :(得分:2)

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