Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 使用SSLStream进行客户端/服务器身份验证_.net_Authentication_Ssl_Sslstream - Fatal编程技术网

.net 使用SSLStream进行客户端/服务器身份验证

.net 使用SSLStream进行客户端/服务器身份验证,.net,authentication,ssl,sslstream,.net,Authentication,Ssl,Sslstream,我有一个客户端和服务器应用程序,它使用SSLStream通过端口80进行通信。客户端和服务器都作为Windows服务运行 一切都在我的测试环境中工作(我的开发计算机,在操作系统Windows 7 Ultimate下)。我的问题是,当我将客户机和服务器应用程序部署到它们的部署环境(服务器在Windows server 2008上,客户机在Windows server 2003上)时,它不工作,我得到错误:“客户机和服务器无法通信,因为它们没有通用的算法” 请注意,我已经使用makecert命令安装

我有一个客户端和服务器应用程序,它使用SSLStream通过端口80进行通信。客户端和服务器都作为Windows服务运行

一切都在我的测试环境中工作(我的开发计算机,在操作系统Windows 7 Ultimate下)。我的问题是,当我将客户机和服务器应用程序部署到它们的部署环境(服务器在Windows server 2008上,客户机在Windows server 2003上)时,它不工作,我得到错误:“客户机和服务器无法通信,因为它们没有通用的算法” 请注意,我已经使用makecert命令安装了相同的证书(在下面的“First”部分中列出)

此外,当我放弃尝试让客户端在Windows Server 2003计算机下进行身份验证时,我将它移到了一台全新/不同的Windows Server 2008计算机上。。然后出现了一个新的错误,即“提供给包的凭据未被识别”

如果您对此问题有任何经验,请提供建议。在过去的3天里,我一直在做这个,已经消耗了超过20个小时的开发时间。 请记住,当服务器和客户端尝试进行身份验证时,问题会不断发生

首先,我通过makecert.exe使用以下命令生成自签名(?)X509证书:

- makecert -n "CN=Transcert" -r -sv Transcert.pvk Transcert.cer
- makecert -sk Transcert -iv Transcert.pvk -n "CN=Transcert" -ic Transcert.cer Transcert.cer -sr LocalMachine -ss Root 
(请注意,我使用存储位置“LocalMachine”,因为据我所知,Windows服务通过LocalSystem帐户使用此存储位置,我可能错了?)

其次,在服务器上,我通过以下代码从存储中检索证书:

X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509CertificateCollection cert = store.Certificates.Find(X509FindType.FindBySubjectName, "Transcert", false);
if (cert.Count > 0)
{
  return cert[0];
}
第三,在服务器上,我开始监听端口80上的TCP客户端:

public virtual void StartListening()
{
  sslServer = new TcpListener(HostPort);

  sslServer.Start();

  AcceptClientThread = new Thread(new ThreadStart(AcceptClientThread_Run));
  AcceptClientThread.Start();
}

private void AcceptClientThread_Run()
{
  try
  {
    TcpClient client = sslServer.AcceptTcpClient();

    ProcessNewClient(client);
  }
  catch (Exception ex)
  {

  }

  AcceptClientThread_Run();
}
第四,在服务器上,我准备了客户端连接时要处理的代码:

  SslClient = pSslClient;
  SSLCertificate = pSSLCertificate;

  _SslStream = new SslStream(SslClient.GetStream());
  _SslStream.AuthenticateAsServer(SSLCertificate, false, SslProtocols.Tls, false);

  Output = new StreamWriter(_SslStream);
  Output.AutoFlush = true;
  Input = new StreamReader(_SslStream);

  ReadThread = new Thread(new ThreadStart(ReadIncomingData));
  ReadThread.Start();
最后,在客户机上,我准备了将客户机连接到服务器的代码:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;

    sslClient = new TcpClient();
    sslClient.Connect(HostAddress, HostPort);

    //ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };

    sslStream = new SslStream(sslClient.GetStream(), false, new RemoteCertificateValidationCallback(CertificateValidationCallback));
    sslStream.AuthenticateAsClient("Trancert");

    showSslInfo(HostAddress, sslStream, true);

--以上是与此问题相关的所有可用信息--

如果使用相同的服务器证书,相同的代码在一台机器上工作,而不是在另一台机器上工作,那么我将再次检查私钥是否与第二台机器上的服务器证书一起正确导入


在certificate Manager MMC管理单元中查看证书的属性,您应该会看到“您有一个与此证书对应的私钥”旁边的小密钥图标。

如果相同的代码在一台机器上工作,而不是在另一台机器上工作,则使用相同的服务器证书,然后,我将再次检查私钥是否与第二台机器上的服务器证书一起正确导入

在certificate Manager MMC管理单元中查看证书的属性,您应该会看到“you have a private key that recepended to this certificate”(您有一个与此证书相对应的私钥)旁边的小密钥图标