1

CCProxyに似たプロキシサーバーアプリケーションを開発しています。HTTPでは正常に機能しますが、HTTPSでは機能しません。AuthenticateAsServer()メソッドがSslStreamオブジェクトで呼び出された場合のスロー例外。また、適切な証明書を提供したかどうかもわかりません。証明書の作成方法もわかりません。オンラインでダウンロードしたコードに付属の証明書を提供しました。コードは次のとおりです。

 private static void DoHttpProcessing(TcpClient client)
    {
        Stream clientStream = client.GetStream();
        Stream outStream = clientStream; 
        SslStream sslStream = null;
        StreamReader clientStreamReader = new StreamReader(clientStream);
        CacheEntry cacheEntry = null;
        MemoryStream cacheStream = null;

        if (Server.DumpHeaders || Server.DumpPostData || Server.DumpResponseData)
        {
            Monitor.TryEnter(_outputLockObj, TimeSpan.FromMilliseconds(-1.0));
        }

        try
        {
            //read the first line HTTP command
            String httpCmd = clientStreamReader.ReadLine();
            if (String.IsNullOrEmpty(httpCmd))
            {
                clientStreamReader.Close();
                clientStream.Close();
                return;
            }
            //break up the line into three components
            String[] splitBuffer = httpCmd.Split(spaceSplit, 3);

            String method = splitBuffer[0];
            String remoteUri = splitBuffer[1];
            Version version = new Version(1, 0);

            HttpWebRequest webReq;
            HttpWebResponse response = null;
            if (splitBuffer[0].ToUpper() == "CONNECT")
            {

                remoteUri = "https://" + splitBuffer[1];
                while (!String.IsNullOrEmpty(clientStreamReader.ReadLine())) ;
                StreamWriter connectStreamWriter = new StreamWriter(clientStream);
                connectStreamWriter.WriteLine("HTTP/1.0 200 Connection established");
                connectStreamWriter.WriteLine(String.Format("Timestamp: {0}", DateTime.Now.ToString()));
                connectStreamWriter.WriteLine("Proxy-agent: matt-dot-net");
                connectStreamWriter.WriteLine();
                connectStreamWriter.Flush();

                sslStream = new SslStream(clientStream, false);

                try
                {
             // HERE I RECEIVE EXCEPTION
                    sslStream.AuthenticateAsServer(_certificate, false, SslProtocols.Tls | SslProtocols.Ssl3 | SslProtocols.Ssl2, true);


                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    sslStream.Close();
                    clientStreamReader.Close();
                    connectStreamWriter.Close();
                    clientStream.Close();
                    return;
                }//further code goes here...

また、sslStream.AuthenticateAsServerの代わりに、ssStream.AuthenticateAsClientメソッドを使用すると、「SSPIの呼び出しに失敗しました。内部例外を参照してください」というメッセージとともにAuthenticationExceptionが発生します。InnerExceptionは、「受信したメッセージが予期しないか、形式が正しくありませんでした」というメッセージを表示します。

sslstream.AuthenticateAsServer()メソッドを使用している場合、新しいHTTPSホストごとに証明書を作成し、このメソッドで渡す必要があります。自己署名証明書を提供すると、要求は成功します。しかし、問題は、証明書を手動で作成し続け、それをAuthenticateAsServer()に割り当てる新しいHTTPS要求がいくつあるかということです。

4

1 に答える 1

0

サーバー側の証明書の場合、ワイルドカード証明書 (*.localhost.local) が存在する可能性がありますが、ほとんどの証明書は FQDN (つまり、server1.localhost.local) に対応しています。AuthenticateAsClient メソッドを使用する場合、1) 証明書にクライアント認証用の拡張キー使用法がないか、2) 証明書/秘密キーを読み取るための正しいパスワードを渡さなかった可能性があります。これらの両方のハードルをかなり早く乗り越えるために、OpenSSL CA を作成してから、CA とサーバー証明書を生成することをお勧めします。これを行う方法についてはたくさんのドキュメントがあり、これまで作成したことがない人には 30 分かかるはずです....(また、証明書を pkcs12 拡張機能にエクスポートして、CA をサーバー証明書にチェーンすることをお勧めします。 )。

于 2013-03-06T23:47:41.337 に答える