【问题标题】:SSL Connection is failing without client side authenticationSSL 连接在没有客户端身份验证的情况下失败
【发布时间】:2018-10-06 11:31:16
【问题描述】:

我读到客户端身份验证是可选的,所以我试图连接到我的 SSL 服务器而不在客户端进行身份验证。当我这样做时,我在服务器上收到以下错误:

, in accept_connection
    ssl_version=ssl.PROTOCOL_SSLv23
  File "/usr/lib/python2.7/ssl.py", line 933, in wrap_socket
    ciphers=ciphers)
  File "/usr/lib/python2.7/ssl.py", line 601, in __init__
    self.do_handshake()
  File "/usr/lib/python2.7/ssl.py", line 830, in do_handshake
    self._sslobj.do_handshake()
SSLEOFError: EOF occurred in violation of protocol (_ssl.c:590)

这是工作的服务器和客户端代码,当我在客户端进行身份验证时一切正常,但是当我注释掉该行时会出现错误。

服务器(python):

def accept_connection(self, sock):
    client, (addr, port) = sock.accept()
    sslclient = ssl.wrap_socket(
        client,
        server_side=True,
        certfile=self.ssl_cert_file,
        keyfile=self.ssl_key_file,
        ssl_version=ssl.PROTOCOL_SSLv23
    )

客户端(C#):

public bool Connect()
    {
        try
        {
            client = new TcpClient(this.ServerAddress, this.ServerPort);

            sslStream = new SslStream(
                client.GetStream(),
                false,
                new RemoteCertificateValidationCallback(ValidateCert),
                null
            );

            try
            {
                sslStream.AuthenticateAsClient(this.ServerAddress);
            }
            catch (AuthenticationException e)
            {
                sslStream = null;
                client.Close();
                client = null;
                return false;
            }
        }
        catch (Exception e)
        {
            return false;
        }

        return true;
    }

以上是没有错误的工作代码。

当我在客户端注释掉以下代码时:

//sslStream.AuthenticateAsClient(this.ServerAddress);

上面提到的python错误出现了,客户端连接没有抛出任何异常并继续运行直到它第一次读取,然后失败:

This operation is only allowed using a successfully authenticated context.

如果我不打电话给AuthenticateAsClient,我该怎么做?

这就是我生成证书文件和密钥文件的方式

openssl req -x509 -newkey rsa:1024 -keyout my.key -out my.crt -days 365 -nodes -subj "/C=US/ST=VA/L=Junk/O=None/OU=Junk/CN=example.local"

Python 是第 2 版。

也许我刚刚被误导,对 AuthenticateAsClient 的调用是可选的?

【问题讨论】:

    标签: c# python ssl ssl-certificate


    【解决方案1】:

    Ssl 客户端证书 身份验证确实是可选的。当客户端将其证书发送到服务器时,服务器会验证此证书是否有效,是服务器所期望的,并使用该证书对客户端进行身份验证。

    但是,这不是由

    执行的
    sslStream.AuthenticateAsClient(this.ServerAddress);
    

    如文档所述,此方法是

    由客户端调用以验证服务器和可选的客户端 在客户端-服务器连接中。

    对服务器进行身份验证(验证其证书是否有效、已为预期域颁发、由受信任的机构颁发)是 ssl 握手中的必需步骤。例如,使用this link 的描述,我们看到第 3 步是:

    SSL 或 TLS 客户端验证服务器的数字证书

    服务器等待客户端执行此步骤的结果。因此,如果您通过评论对AuthenticateAsClient 的调用来跳过此步骤 - 您的 python 服务器正确地抱怨协议违规。

    要使用客户端身份验证,您将使用另一个重载:

    X509CertificateCollection clientCerts = GetClientCerts();
    sslStream.AuthenticateAsClient(this.ServerAddress, clientCerts, true);
    

    由于您没有这样做 - 您没有执行(可选)客户端身份验证。

    【讨论】:

      猜你喜欢
      • 2019-01-08
      • 2014-08-24
      • 2021-04-22
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 2018-03-19
      • 1970-01-01
      • 2016-02-22
      相关资源
      最近更新 更多