title: SSLStream.AuthenticateAsServer "The client and server cannot communicate, because they do not possess a common algorithm"
body: <p>I'm working on a server application that needs to communicate with clients through sockets. In the middle of connection after initial data exchange, clients require a secure connection over sockets.</p>
  <p>So I initiate the secure connection like calling StartupSSLHandshake() method;</p>
  <pre><code>    private void StartupSSLHandshake()
      {
          ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
  
          using (var networkStream = new NetworkStream(this.Connection._Socket, true))
          {
              this.SSLStream = new SslStream(networkStream, false);
              
              try
              {
                  this.SSLStream.AuthenticateAsServer(CertificateHelper.Certificate, true, SslProtocols.Tls, true);
  
                  Console.WriteLine(&quot;Cipher: {0} strength {1}&quot;, SSLStream.CipherAlgorithm, SSLStream.CipherStrength);
                  Console.WriteLine(&quot;Hash: {0} strength {1}&quot;, SSLStream.HashAlgorithm, SSLStream.HashStrength);
                  Console.WriteLine(&quot;Key exchange: {0} strength {1}&quot;, SSLStream.KeyExchangeAlgorithm, SSLStream.KeyExchangeStrength);
                  Console.WriteLine(&quot;Protocol: {0}&quot;, SSLStream.SslProtocol);
  
              }
              catch(AuthenticationException e)
              {
                  Logger.FatalException(e, &quot;Certificate exception&quot;);
              }
          }
      }
  </code></pre>
  <p>Further more I generate my server-sertificate at run time using <a href="http://blogs.msdn.com/b/dcook/archive/2008/11/25/creating-a-self-signed-certificate-in-c.aspx" rel="nofollow noreferrer">http://blogs.msdn.com/b/dcook/archive/2008/11/25/creating-a-self-signed-certificate-in-c.aspx</a></p>
  <p>And here's my CertificateHelper class that generates it if needed:</p>
  <pre><code>public static class CertificateHelper
  {
      public const string SertificateFile = &quot;cert.pfx&quot;;
      public static X509Certificate Certificate = null;
  
      static CertificateHelper()
      {
          if (!CertificateExists())
              Create();
  
          Certificate = new X509Certificate2(SertificateFile, &quot;mypassword&quot;);
      }
  
      private static void Create()
      {
          byte[] certificate = CertificateCreator.CreateSelfSignCertificatePfx(&quot;CN=mydomain.org&quot;, DateTime.Parse(&quot;2011-01-01&quot;), DateTime.Parse(&quot;2013-01-01&quot;), &quot;mypassword&quot;);
  
          using (var writer = new BinaryWriter(File.Open(SertificateFile, FileMode.Create)))
          {
              writer.Write(certificate);
          }
      }
  
      public static bool CertificateExists()
      {
          return File.Exists(SertificateFile);
      }
  }
  </code></pre>
  <p>So when I try to run it against clients (which are probably using OpenSSL libs), no matter what I try, I just get &quot;The client and server cannot communicate, because they do not possess a common algorithm&quot; exception;</p>
  <pre><code>[15.11.2011 11:01:06.771] [Fatal] [Server]: Certificate exception - [Exception] System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---&gt; System.ComponentModel.Win32Exception: The client and server cannot communicate, because they do not possess a common algorithm
     --- End of inner exception stack trace ---
     at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
     at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
     at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
     at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
     at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
     at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
     at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
     at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
     at System.Net.Security.SslStream.AuthenticateAsServer(X509Certificate serverCertificate, Boolean clientCertificateRequired, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
     at Server.StartupSSLHandshake() in xyz.cs:line 293
  </code></pre>
  <p>So I enabled socket-tracing and here's the output;</p>
  <pre><code>System.Net Information: 0 : [4828] SecureChannel#60869981::.ctor(hostname=?124, #clientCertificates=0, encryptionPolicy=RequireEncryption)
  System.Net Information: 0 : [4828] Enumerating security packages:
  System.Net Information: 0 : [4828]     Negotiate
  System.Net Information: 0 : [4828]     NegoExtender
  System.Net Information: 0 : [4828]     Kerberos
  System.Net Information: 0 : [4828]     NTLM
  System.Net Information: 0 : [4828]     Schannel
  System.Net Information: 0 : [4828]     Microsoft Unified Security Protocol Provider
  System.Net Information: 0 : [4828]     WDigest
  System.Net Information: 0 : [4828]     TSSSP
  System.Net Information: 0 : [4828]     pku2u
  System.Net Information: 0 : [4828]     CREDSSP
  System.Net.Sockets Verbose: 0 : [4828] Socket#5655257::Receive()
  System.Net.Sockets Verbose: 0 : [4828] Data from Socket#5655257::Receive
  System.Net.Sockets Verbose: 0 : [4828] 00000000 : 16 03 01 00 3B                                  : ....;
  System.Net.Sockets Verbose: 0 : [4828] Exiting Socket#5655257::Receive()    -&gt; 5#5
  System.Net.Sockets Verbose: 0 : [4828] Socket#5655257::Receive()
  System.Net.Sockets Verbose: 0 : [4828] Data from Socket#5655257::Receive
  System.Net.Sockets Verbose: 0 : [4828] 00000005 : 01 00 00 37 03 01 4E C2-2A 52 03 2A 4F BC 0F 94 : ...7..N.*R.*O...
  System.Net.Sockets Verbose: 0 : [4828] 00000015 : E2 AE B5 1D 99 1A 21 D3-DF 6C 16 47 71 23 D0 F3 : ......!..l.Gq#..
  System.Net.Sockets Verbose: 0 : [4828] 00000025 : AD E9 A9 3F 22 E8 00 00-0A 00 8D 00 8B 00 8C 00 : ...?&quot;...........
  System.Net.Sockets Verbose: 0 : [4828] 00000035 : 8A 00 FF 01 00 00 04 00-23 00 00                : ........#..
  System.Net.Sockets Verbose: 0 : [4828] Exiting Socket#5655257::Receive()    -&gt; 59#59
  System.Net Information: 0 : [4828] SecureChannel#60869981 - Locating the private key for the certificate: [Version]
    V3
  
  [Subject]
    CN=mydomain.org
    Simple Name: mydomain.org
    DNS Name: mydomain.org
  
  [Issuer]
    CN=mydomain.org
    Simple Name: mydomain.org
    DNS Name: mydomain.org
  
  [Serial Number]
    2C7ECC7CAEB576AB48F47A5F356D5B61
  
  [Not Before]
    01.01.2011 00:00:00
  
  [Not After]
    01.01.2013 00:00:00
  
  [Thumbprint]
    5DA4607C89339CB550DF52A2608B9ABFBFFC90EB
  
  [Signature Algorithm]
    sha1RSA(1.2.840.113549.1.1.5)
  
  [Public Key]
    Algorithm: RSA
    Length: 1024
    Key Blob: 30 81 89 02 81 81 00 a9 e8 b1 cc 71 e5 7e 1a c8 ba bc c9 32 bb e3 b3 f3 66 d6 9b bb 3d b8 41 0d ef 45 06 cc f5 49 bf 10 7a 39 28 60 e5 33 93 b1 d1 78 f6 97 fc 28 c5 cc 66 28 db 43 8a 8e 26 39 cb 84 c9 fe 96 a7 83 e8 f7 03 37 6a 91 fe 36 1c bf 66 5e 1e 2e 41 62 3f 41 ab d9 cf ac 4d 4c cd 79 3d ab 97 9d ce 57 ec 60 bb f8 65 d8 ad 5d 24 0a e2 a0 33 9e 7d 01 41 77 7a 0d 0e 13 36 dc ee 16 eb 35 ab 89 2c 11 02 03 01 00 01
    Parameters: 05 00
  
  [Private Key]
    Key Store: User
    Provider Name: Microsoft Enhanced Cryptographic Pro....
  System.Net Information: 0 : [4828] SecureChannel#60869981 - Certificate is of type X509Certificate2 and contains the private key.
  System.Net Information: 0 : [4828] AcquireCredentialsHandle(package = Microsoft Unified Security Protocol Provider, intent  = Inbound, scc     = System.Net.SecureCredential)
  System.Net Information: 0 : [4828] AcceptSecurityContext(credential = System.Net.SafeFreeCredential_SECURITY, context = (null), inFlags = MutualAuth, ReplayDetect, SequenceDetect, Confidentiality, AllocateMemory, InitIntegrity)
  System.Net Information: 0 : [4828] AcceptSecurityContext(In-Buffer length=64, Out-Buffer length=0, returned code=AlgorithmMismatch).
  System.Net.Sockets Verbose: 0 : [4828] Socket#5655257::Dispose()
  </code></pre>
  <p>It tells me about that AlgorithmMismatch;</p>
  <p>System.Net Information: 0 : [4828] AcceptSecurityContext(In-Buffer length=64, Out-Buffer length=0, returned code=AlgorithmMismatch).</p>
  <p>Further found that client uses this chippers;</p>
  <ul>
  <li>Cipher Suite: TLS_PSK_WITH_AES_256_CBC_SHA (0x008d)</li>
  <li>Cipher Suite: TLS_PSK_WITH_3DES_EDE_CBC_SHA (0x008b)</li>
  <li>Cipher Suite: TLS_PSK_WITH_AES_128_CBC_SHA (0x008c)</li>
  <li>Cipher Suite: TLS_PSK_WITH_RC4_128_SHA (0x008a)</li>
  <li>Cipher Suite: TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)</li>
  </ul>
  <p>Does SSLStream any support these?</p>