2011-11-15 22 views
0

私はソケット経由でクライアントと通信する必要があるサーバーアプリケーションで作業しています。最初のデータ交換後の接続の途中では、クライアントはソケットを介して安全な接続が必要です。SSLStream.AuthenticateAsServer "クライアントとサーバーは共通のアルゴリズムを持っていないため通信できません"

私はStartupSSLHandshake()メソッドのように安全な接続を開始します。

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("Cipher: {0} strength {1}", SSLStream.CipherAlgorithm, SSLStream.CipherStrength); 
       Console.WriteLine("Hash: {0} strength {1}", SSLStream.HashAlgorithm, SSLStream.HashStrength); 
       Console.WriteLine("Key exchange: {0} strength {1}", SSLStream.KeyExchangeAlgorithm, SSLStream.KeyExchangeStrength); 
       Console.WriteLine("Protocol: {0}", SSLStream.SslProtocol); 

      } 
      catch(AuthenticationException e) 
      { 
       Logger.FatalException(e, "Certificate exception"); 
      } 
     } 
    } 

はまた、より多くの私はhttp://blogs.msdn.com/b/dcook/archive/2008/11/25/creating-a-self-signed-certificate-in-c.aspx

を使用して実行時に私のサーバー・sertificateを生成し、ここで、必要であれば、それを生成し、私のCertificateHelperクラスです:私はに対してそれを実行しようとすると、

public static class CertificateHelper 
{ 
    public const string SertificateFile = "cert.pfx"; 
    public static X509Certificate Certificate = null; 

    static CertificateHelper() 
    { 
     if (!CertificateExists()) 
      Create(); 

     Certificate = new X509Certificate2(SertificateFile, "mypassword"); 
    } 

    private static void Create() 
    { 
     byte[] certificate = CertificateCreator.CreateSelfSignCertificatePfx("CN=mydomain.org", DateTime.Parse("2011-01-01"), DateTime.Parse("2013-01-01"), "mypassword"); 

     using (var writer = new BinaryWriter(File.Open(SertificateFile, FileMode.Create))) 
     { 
      writer.Write(certificate); 
     } 
    } 

    public static bool CertificateExists() 
    { 
     return File.Exists(SertificateFile); 
    } 
} 

だからクライアント(おそらくOpenSSLライブラリを使用しています)は、私が試しても、 "クライアントとサーバは共通のアルゴリズムを持っていないため通信できません"という例外があります。

[15.11.2011 11:01:06.771] [Fatal] [Server]: Certificate exception - [Exception] System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> 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 

私はソケットトレースを有効にしました。ここに出力があります。

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() -> 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 : ...?"........... 
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() -> 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() 

これは、AlgorithmMismatchに関するものです。 0:[4828] AcceptSecurityContext(バッファ内の長さ= 64、アウトバッファの長さ= 0、返されるコード= AlgorithmMismatch)0304

さらに、クライアントがこのチッパーを使用していることがわかりました。

  • 暗号スイート:TLS_PSK_WITH_AES_256_CBC_SHA(0x008d)
  • 暗号スイート:TLS_PSK_WITH_3DES_EDE_CBC_SHA(0x008b)
  • 暗号スイート:TLS_PSK_WITH_AES_128_CBC_SHA(0x008c)
  • 暗号スイート:TLS_PSK_WITH_RC4_128_SHA(0x008a)
  • 暗号スイート:TLS_EMPTY_RENEGOTIATION_INFO_SCSV (0x00ff)

SSLStreamはこれらをサポートしていますか?

答えて

5

Windowsでは、TLS_PSK暗号化キーのいずれもサポートしていないため、サーバーにはクライアントとの共通アルゴリズムはありません。非PSKベースの暗号スイートを使用するようにクライアントを設定できる場合、動作させることができます。

PSKは「PreShared Key」の略語なので、TLSチャネルを確立するために共有鍵(パスワードなど)を使用するすべての証明書です。このようなTLS接続には証明書は必要ありませんが、Windowsではこれがサポートされていません。

+0

さらに、それをサポートするライブラリがあっても、このクライアントで文書化する必要があります(あらかじめキーを共有する方法を定義する場合のみ...) – Bruno

+0

もっと説明できますか?どういう意味ですか?私は同じ問題を抱えています。私はクライアントがサーバーに接続するために証明書ファイルから公開鍵を取得し、これらのすべてがsithlStreamで行われると思った。問題の解決は何ですか? – virtouso

関連する問題