Reputation: 1118
I have a WCF service which uses NetTcpBinding with message security and username authentication. Before that I was using WsHttpBinding but I switched to NetTcp because I could use callbacks.
My service config looks like this:
<service behaviorConfiguration="WcfServiceLibrary1.ServiceBehavior" name="WcfServiceLibrary1.Service">
<endpoint
address="net.tcp://localhost:9000/Design_Time_Addresses/WcfServiceLibrary1/Service/"
binding="netTcpBinding"
bindingConfiguration="NetTCPbinding"
contract="WcfServiceLibrary1.IService"
name="NetTCPBinding">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary1/Service/" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="NetTCPbinding">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="WcfServiceLibrary1.ServiceBehavior">
<serviceCredentials>
<serviceCertificate findValue="ServerCert"
storeLocation="CurrentUser"
storeName="TrustedPeople"
x509FindType="FindBySubjectName" />
<userNameAuthentication
userNamePasswordValidationMode="MembershipProvider"
membershipProviderName="CustomMembershipProvider" />
</serviceCredentials>
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True" />
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="MyRoleProvider" />
<!-- Logs when an authentication failure -->
<serviceSecurityAudit auditLogLocation="Application"
suppressAuditFailure="true"
serviceAuthorizationAuditLevel="Failure"
messageAuthenticationAuditLevel="SuccessOrFailure" />
</behavior>
</serviceBehaviors>
</behaviors>
I assume the service credentials -in this case the certificate- are used so that the service can sign all the data that it sends to the client, so the client can know that it is communicating with the correct service.
The client config is the following:
<behaviors>
<endpointBehaviors>
<behavior name="messageSecurityBehavior">
<clientCredentials>
<clientCertificate storeLocation="CurrentUser"
storeName="TrustedPeople"
x509FindType="FindBySubjectName"
findValue="ClientCert" />
<serviceCertificate>
<authentication certificateValidationMode="None" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="NetTCPBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="UserName" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:9000/Design_Time_Addresses/WcfServiceLibrary1/Service/"
binding="netTcpBinding" bindingConfiguration="NetTCPBinding"
contract="IService" name="NetTCPBinding" behaviorConfiguration="messageSecurityBehavior">
<identity>
<certificate encodedValue="AwAAAAEAAAAUAAAAQerRMlEg2a66HMxD/8El6LutassgAAAAAQAAAOwBAAAwggHoMIIBVaADAgECAhAzOWVhNWUzM2Y5MzUwNzFhMAkGBSsOAwIdBQAwIjELMAkGA1UEBhMCVVMxEzARBgNVBAMTClNlcnZlckNlcnQwHhcNMTIwMTE3MTk1NDQ2WhcNMjUwOTI1MTk1NDQ2WjAiMQswCQYDVQQGEwJVUzETMBEGA1UEAxMKU2VydmVyQ2VydDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAs6SaYi3pDDIOuXeCe7HgOOTvOpwajKdxM8MzZpkK3l+DqkriMQUx9DT5I9WZvNK5FMuorLueG5adWkTgWpvttC7Sp8CJ//A+PbPewiAU4L3Txln6dX3jHZFd99LY/58/2AzY8ln2NykQFzz1DdmVeyShG9ktVsX82Ogz60lzpeUCAwEAAaMnMCUwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDgYDVR0PBAcDBQD6AAAAMAkGBSsOAwIdBQADgYEAMGQ7fIW34CYjybCc0gWOLaxeRFiNHmX/dgxqPIWGgg3uc0avz1GHJ3uMHcPAZBKcw9QpbccALpqZxZzkDBxufWjRni+8XCzeAKUqaB7XaJTYYUYBbz7/2+EuaAw7/vF4JTtZGWhPkHZZcX5+Oyo2ktK0z24MfXP2Ggy+IsQJ2JM=" />
</identity>
</endpoint>
</client>
All of this works fine. I've read that the service certificate is used to encrypt the client credentials and the messages. Then why do we need the algorithm specified in AlgorithmSuite? What does it encrypt?
I need to understand this well so I can explain it in my thesis.
Upvotes: 4
Views: 3461
Reputation: 63840
The certificate leads to the key that's used for encryption of the message (I'm not sure if it's directly used as a key itself, or used to negotiate a key). The AlgorithmSuite determines the algorithm, which will use that key to encrypt the message.
Why do you need to specify an algorithm?
Because you need to tell WCF how it should encrypt your message. The used algorithm is also identified in the SOAP message, because the receiving party has to know what algorithm to use to decrypt the message. Note that if you don't set an algorithm explicitly, it will still have a value, default Basic256 for NetTcp (source).
If you enable message tracing, you'd see something along these lines in the SOAP body for the appropriate (encrypted) action for your service operation:
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
If you would change the AlgorithmSuite to Basic128
the above would show aes128-cbc
in the latter bit of the Algorithm attribute.
In the message trace, right before the action corresponding to your service operation, there will be several actions in the http://schemas.xmlsoap.org/ws/2005/02/trust/...
range to negotiate all the security options. On the Message Security in WCF MSDN page you can see that WCF uses the WS-Security specification. For more information on this spec you could go to this page where I found the WS-Security 2004 spec (pdf). This may be also be useful if you need official references for your thesis.
What does it encrypt?
The algorithm encrypts both the credentials and the message (using the key that was obtained with help from the certificate), just like you already stated :-). You can see this if you enable message tracing: both the credentials and the message body will be encrypted with the selected algorithm.
Disclaimer: I'm still somewhere in the slope of the WCF learning curve, so if your thesis grade depends on this you'd better double check my claims :D
Upvotes: 1