【问题标题】:Exception in ssl certificate codessl 证书代码中的异常
【发布时间】:2015-04-21 06:58:05
【问题描述】:

我与 sslStream 建立了客户端服务器套接字连接,但是当代码到达 AuthenticateAsServer 行时,服务器上出现异常我在互联网上搜索但找不到一个好的答案,为什么会发生这种情况。 我在我的项目中创建了 .pfx 测试文件并为其设置了一个简单的密码。我不知道问题是不是来自文件。

异常在行:sslStream.AuthenticateAsServer(certificate);

基本例外是:调用 sspi 失败

内部异常是:客户端客户端和服务器无法通信,因为它们不具备通用算法

服务器有点长,我添加了发生异常的部分代码和所有客户端代码:

这是服务器:

 public void AcceptCallBack(IAsyncResult ar) 
        {
        //    clients.Add(new myClient(server.EndAccept(ar)));
        //    try
       //     {
                myClient c = new myClient();

               // Socket handle = (Socket)ar.AsyncState;
                TcpListener handle = (TcpListener)ar.AsyncState;
                byte[] buff=new byte[2048] ;
               // Socket hand = handle.EndAccept(out buff,ar);
                TcpClient hand = handle.EndAcceptTcpClient(ar);
                dowork.Set();
                c.tcp = hand;
                clients.Add(c);
               // hand.BeginReceive(c.buffer, 0, c.buffer.Length, SocketFlags.None, new AsyncCallback(receiveIDCallBack), c);
                using (SslStream sslStream = new SslStream(hand.GetStream()))
                {
                    sslStream.AuthenticateAsServer(certificate);
                    // ... Send and read data over the stream
                    sslStream.BeginWrite(buff,0,buff.Length,new AsyncCallback(sendCallBack),c);
                    count++;
                    sslStream.BeginRead(c.buffer,0,c.buffer.Length,new AsyncCallback(receiveIDCallBack),c);
                }
       //     }
         //   catch(Exception)
          //  {

         //   }
        }//end of acceptcallback function

这是客户:

using UnityEngine;
using System.Collections;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Net.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
public class sslCode : MonoBehaviour {


   // private Socket _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    private byte[] _recieveBuffer = new byte[8142];

   static string server = "127.0.0.1";
    TcpClient client;

    public string message;
    public string receive;
    public string send;
    private void SetupServer()
    {
        try
        {

           // client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1500));
            client = new TcpClient(server,1500);
            message = "connected";
        }
        catch (SocketException ex)
        {
            Debug.Log(ex.Message);
            message = ex.Message;
        }

       // _clientSocket.BeginReceive(_recieveBuffer, 0, _recieveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
        // Create a secure stream
        using (SslStream sslStream = new SslStream(client.GetStream(), false,
            new RemoteCertificateValidationCallback(ValidateServerCertificate), null))
        {
            sslStream.AuthenticateAsClient(server);

            // ... Send and read data over the stream
            sslStream.BeginRead(_recieveBuffer, 0, _recieveBuffer.Length, new AsyncCallback(ReceiveCallback),null);
        }

    }

    private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        throw new NotImplementedException();
    }// end of setup server

    private void ReceiveCallback(IAsyncResult AR)
    {
        //Check how much bytes are recieved and call EndRecieve to finalize handshake
        using (SslStream sslStream = new SslStream(client.GetStream(), false,
       new RemoteCertificateValidationCallback(ValidateServerCertificate), null))
        {
            sslStream.AuthenticateAsClient(server);
            // ... Send and read data over the stream


            int recieved = sslStream.EndRead(AR);

            if (recieved <= 0)
                return;

            //Copy the recieved data into new buffer , to avoid null bytes
            byte[] recData = new byte[recieved];
            Buffer.BlockCopy(_recieveBuffer, 0, recData, 0, recieved);

            //Process data here the way you want , all your bytes will be stored in recData

            receive = Encoding.ASCII.GetString(recData);

            //Start receiving again
            sslStream.BeginRead(_recieveBuffer, 0, _recieveBuffer.Length, new AsyncCallback(ReceiveCallback), null);
        }
    }// end of receiveCallBack

    private void SendData(string dd)
    {
        using (SslStream sslStream = new SslStream(client.GetStream(), false,
       new RemoteCertificateValidationCallback(ValidateServerCertificate), null))
        {
          sslStream.AuthenticateAsClient(server);

            // ... Send and read data over the stream

            byte[] data = Encoding.ASCII.GetBytes(dd);
            SocketAsyncEventArgs socketAsyncData = new SocketAsyncEventArgs();
            socketAsyncData.SetBuffer(data, 0, data.Length);
           sslStream.BeginWrite(data,0,data.Length,new AsyncCallback(sendcallback),null);
            send = dd;
            sslStream.BeginRead(_recieveBuffer, 0, _recieveBuffer.Length, new AsyncCallback(ReceiveCallback), null);
        }
    }

    private void sendcallback(IAsyncResult ar)
    {

    }// end of send data

这可能是在vs或windows的选项中生成的证书文件的问题吗?

我在互联网上进行了更多搜索,并且我认为我用于证书文件的算法不匹配的可能性以及 Windows 8.1 可以理解的内容。我真的不知道....

vs 让我为我的证书制作的算法是“sha256RSA”和“sha1RSA” 感谢您的帮助

【问题讨论】:

  • 发布您收到的确切消息及其出现的位置。
  • @500-InternalServerError 感谢您的回答。我编辑了帖子并以粗体添加了行和消息。
  • 只是猜测,但这可能是因为您的客户端方法 ValidateServerCertificate 中的代码?据推测,一旦服务器发送其凭据,就会调用它,并且 throw 导致双方中止?尝试将throw... 替换为return true;
  • @Dusty 谢谢你的回答。我想你是对的。我做了,但我仍然有问题。

标签: c# sockets visual-studio-2012 ssl windows-8.1


【解决方案1】:

谢谢我的朋友们,我终于找到了我的问题。

代码需要稍作修改,但主要问题不是代码。

问题出在证书文件的工作方式上。我刚刚生成了一个 pfx 文件并将其地址提供给下面的代码:

sslStream.AuthenticateAsServer(server);

但是现在我在 Internet 选项中制作了 pfx 格式并将其导入到个人部分,然后将其导出到受信任的根部分,因此将生成该 pfx 文件的 cer 格式,其中仅包含该 pfx 文件的公钥。

所以现在代码运行得很好。

【讨论】:

    【解决方案2】:

    我在我的项目中制作了 .pfx 测试文件

    这是一个大红旗。在不了解您使用的工具的情况下,最好的猜测是您创建了一个签名 证书。它不适合密钥交换。此blog post 涵盖的故障模式。

    在不了解您的操作系统的情况下,我不得不猜测您使用的是 Linux。在这种情况下,this question 应该会有所帮助。如果这是一个错误的猜测,那么请通过谷歌搜索“创建自签名 ssl 证书,添加适当的关键字来选择您的操作系统和/或工具链。

    【讨论】:

    • 我的标签是 c#,所以肯定是它的 windows 和它的 8.1,在最常见的情况下,你使用 vs 来处理 c#。请
    • 抱歉,2 天后获得赏金的人可能已经查看了所有可能的链接。我以前看过你的链接,但没有一个能解决我的问题。你可以评论你的链接